summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@osg.samsung.com>2016-03-07 14:47:26 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2016-03-07 14:47:26 -0500
commit114a6041666111ee9f12723a8ba22a9135f71ae1 (patch)
tree395be1666d9a5b319c739b2dd73a1a904faf3056
parent7e91bc721abbc0b12e34e394e52a121aaa0f1fb6 (diff)
downloadenlightenment-114a6041666111ee9f12723a8ba22a9135f71ae1.tar.gz
apply x11 focus/unfocus using jobs
if multiple x11 clients receive focus during the same mainloop iteration, an almost unbreakable cycle of window focus chaining will occur, resulting in both windows being focused simultaneously--or so it appears--which results in no window being able to receive input. to avoid this, ensure that only one x11 client can receive focus in a given loop iteration
-rw-r--r--src/bin/e_comp_x.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c
index 8eb8173a43..b1b04f32da 100644
--- a/src/bin/e_comp_x.c
+++ b/src/bin/e_comp_x.c
@@ -54,6 +54,10 @@ static Eina_Hash *alarm_hash = NULL;
static Evas_Point mouse_in_coords = {-1, -1};
static Ecore_Job *mouse_in_job;
+static E_Client *focus_job_client;
+static Ecore_Job *focus_job;
+static E_Client *unfocus_job_client;
+static Ecore_Job *unfocus_job;
static Ecore_Idle_Enterer *_e_comp_x_post_client_idler = NULL;
static Ecore_Idle_Enterer *_x_idle_flush = NULL;
static Eina_List *post_clients = NULL;
@@ -4471,16 +4475,32 @@ _e_comp_x_hook_client_new(void *d EINA_UNUSED, E_Client *ec)
}
static void
-_e_comp_x_hook_client_focus_unset(void *d EINA_UNUSED, E_Client *ec)
+_e_comp_x_hook_client_focus_unset_job(void *d EINA_UNUSED)
{
+ E_Client *ec = unfocus_job_client;
+ unfocus_job = NULL;
+ if (!unfocus_job_client) return;
+ unfocus_job_client = NULL;
E_COMP_X_PIXMAP_CHECK;
_e_comp_x_focus_setup(ec);
_e_comp_x_focus_check();
}
static void
-_e_comp_x_hook_client_focus_set(void *d EINA_UNUSED, E_Client *ec)
+_e_comp_x_hook_client_focus_unset(void *d EINA_UNUSED, E_Client *ec)
+{
+ unfocus_job_client = ec;
+ if (!unfocus_job)
+ unfocus_job = ecore_job_add(_e_comp_x_hook_client_focus_unset_job, NULL);
+}
+
+static void
+_e_comp_x_hook_client_focus_set_job(void *d EINA_UNUSED)
{
+ E_Client *ec = focus_job_client;
+ focus_job = NULL;
+ if (!focus_job_client) return;
+ focus_job_client = NULL;
focus_time = ecore_x_current_time_get();
focus_canvas_time = 0;
if (!e_client_has_xwindow(ec))
@@ -4506,6 +4526,14 @@ _e_comp_x_hook_client_focus_set(void *d EINA_UNUSED, E_Client *ec)
}
static void
+_e_comp_x_hook_client_focus_set(void *d EINA_UNUSED, E_Client *ec)
+{
+ focus_job_client = ec;
+ if (!focus_job)
+ focus_job = ecore_job_add(_e_comp_x_hook_client_focus_set_job, NULL);
+}
+
+static void
_e_comp_x_hook_client_redirect(void *d EINA_UNUSED, E_Client *ec)
{
E_COMP_X_PIXMAP_CHECK;
@@ -4563,6 +4591,8 @@ _e_comp_x_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
cd = _e_comp_x_client_data_get(ec);
if (mouse_client == ec) mouse_client = NULL;
+ if (focus_job_client == ec) focus_job_client = NULL;
+ if (unfocus_job_client == ec) unfocus_job_client = NULL;
if ((!stopping) && cd && (!cd->deleted))
ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &visible, 1);
if ((!ec->already_unparented) && cd && cd->reparented)
@@ -4956,6 +4986,8 @@ _e_comp_x_del(E_Comp *c)
eina_list_free(c->x_comp_data->retry_clients);
ecore_timer_del(c->x_comp_data->retry_timer);
E_FREE_FUNC(mouse_in_job, ecore_job_del);
+ E_FREE_FUNC(focus_job, ecore_job_del);
+ E_FREE_FUNC(unfocus_job, ecore_job_del);
free(c->x_comp_data);
}