summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2016-06-29 16:23:41 -0500
committerDerek Foreman <derekf@osg.samsung.com>2016-06-29 16:23:41 -0500
commitf391a0fb6724d9efe9aa0c89fe47e2372af8d35d (patch)
tree0d58fc3467255bca06405c2cee8890c266fb4c9c
parentada8e2deac6665700de257b5f7d3d87707976aef (diff)
downloadenlightenment-f391a0fb6724d9efe9aa0c89fe47e2372af8d35d.tar.gz
Fix xdg_shell keyboard enter/leave events
On xdg_shell we should only ever send enter/leave to top level surfaces or GTK becomes sad.
-rw-r--r--src/bin/e_comp_wl.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 19da0217fd..f9e872ab78 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -44,6 +44,25 @@ static int64_t surface_id = 0;
/* local functions */
+static Eina_Bool
+_parent_client_contains_pointer(E_Client *ec)
+{
+ Eina_List *l;
+ E_Client *c, *top = ec;
+
+ while (top->parent) top = top->parent;
+
+ if (top->mouse.in) return EINA_TRUE;
+
+ EINA_LIST_FOREACH(top->comp_data->sub.list, l, c)
+ if (c->mouse.in) return EINA_TRUE;
+
+ EINA_LIST_FOREACH(top->transients, l, c)
+ if ((ec != c) && c->mouse.in) return EINA_TRUE;
+
+ return EINA_FALSE;
+}
+
static struct wl_resource *
_output_resource_find(Eina_List *reslist, struct wl_resource *surface)
{
@@ -606,6 +625,18 @@ _e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj
_e_comp_wl_client_priority_raise(ec);
wc = wl_resource_get_client(ec->comp_data->surface);
+ if (ec->comp_data->is_xdg_surface)
+ {
+ /* If an xdg shell popup's parent already has focus we don't
+ * need to do anything more.
+ */
+ EINA_LIST_FOREACH(e_comp_wl->kbd.focused, l, res)
+ if (wl_resource_get_client(res) == wc) return;
+
+ /* We only kbd focus top level xdg */
+ while (ec->parent) ec = ec->parent;
+ }
+
EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
if (wl_resource_get_client(res) == wc)
e_comp_wl->kbd.focused = eina_list_append(e_comp_wl->kbd.focused, res);
@@ -630,6 +661,16 @@ _e_comp_wl_keyboard_leave(E_Client *ec)
if (!ec->comp_data) return;
if (!ec->comp_data->surface) return;
+ if (ec->comp_data->is_xdg_surface)
+ {
+ /* If we left an xdg popup to enter some other (sub)surface
+ * of the same top level, we don't need to do anything */
+ if (_parent_client_contains_pointer(ec)) return;
+
+ /* We only kbd focus top level xdg */
+ while (ec->parent) ec = ec->parent;
+ }
+
wc = wl_resource_get_client(ec->comp_data->surface);
serial = wl_display_next_serial(e_comp_wl->wl.disp);
t = ecore_time_unix_get();