From b0fb5ae565502f9460afb69fbb0175f2e5d32f36 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 22 May 2013 11:07:01 +0100 Subject: [PATCH] greatly improve pointer focus models by hooking mouse callbacks to the comp win object --- src/bin/e_border.c | 56 +++++++++++++++------------------------------- src/bin/e_comp.c | 54 +++++++++++++++++++++----------------------- 2 files changed, 44 insertions(+), 66 deletions(-) diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 5a004dcca..e835a32b7 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -83,7 +83,6 @@ static Eina_Bool _e_border_cb_config_icon_theme(void *data, static Eina_Bool _e_border_cb_config_mode(void *data, int ev_type, void *ev); - static Eina_Bool _e_border_cb_pointer_warp(void *data, int ev_type, void *ev); @@ -6379,15 +6378,14 @@ _e_border_cb_mouse_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNU E_Border *bd = data; if (grabbed) return; - if (bd == focusing) return; + if ((bd == focusing) || (bd == focused)) return; if (focus_locked && (bd != warp_timer_border)) return; if (e_object_is_del(E_OBJECT(bd))) return; if (bd->desk && bd->desk->animate_count) return; - if (!bd->iconic) - e_focus_event_mouse_in(bd); bd->mouse.current.mx = ev->output.x; bd->mouse.current.my = ev->output.y; - return; + if (!bd->iconic) + e_focus_event_mouse_in(bd); } static Eina_Bool @@ -6399,14 +6397,14 @@ _e_border_cb_mouse_x_in(void *data EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event bd = e_border_find_by_window(ev->event_win); if (!bd) return ECORE_CALLBACK_RENEW; if (bd->input_object) return ECORE_CALLBACK_RENEW; - if (bd == focusing) return ECORE_CALLBACK_RENEW; + if ((bd == focusing) || (bd == focused)) return ECORE_CALLBACK_RENEW; if (focus_locked && (bd != warp_timer_border)) return ECORE_CALLBACK_RENEW; if (e_object_is_del(E_OBJECT(bd))) return ECORE_CALLBACK_RENEW; if (bd->desk && bd->desk->animate_count) return ECORE_CALLBACK_RENEW; - if (!bd->iconic) - e_focus_event_mouse_in(bd); bd->mouse.current.mx = ev->root.x; bd->mouse.current.my = ev->root.y; + if (!bd->iconic) + e_focus_event_mouse_in(bd); return ECORE_CALLBACK_RENEW; } @@ -6423,10 +6421,10 @@ _e_border_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN if (bd->desk && bd->desk->animate_count) return; if (!bd->input_object) if (E_INSIDE(ev->output.x, ev->output.y, bd->x, bd->y, bd->w, bd->h)) return; - if (!bd->iconic) - e_focus_event_mouse_out(bd); bd->mouse.current.mx = ev->output.x; bd->mouse.current.my = ev->output.y; + if (!bd->iconic) + e_focus_event_mouse_out(bd); } static Eina_Bool @@ -6451,10 +6449,10 @@ _e_border_cb_mouse_x_out(void *data EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Even if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) && (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR)) return ECORE_CALLBACK_PASS_ON; - if (!bd->iconic) - e_focus_event_mouse_out(bd); bd->mouse.current.mx = ev->root.x; bd->mouse.current.my = ev->root.y; + if (!bd->iconic) + e_focus_event_mouse_out(bd); return ECORE_CALLBACK_RENEW; } @@ -7035,6 +7033,7 @@ _e_border_eval0(E_Border *bd) { int change_urgent = 0; int rem_change = 0; + Eina_Bool new_cw = !bd->cw; #if (ECORE_VERSION_MAJOR > 1) || (ECORE_VERSION_MINOR >= 8) Eina_Bool need_desk_set = EINA_FALSE; #endif @@ -8145,12 +8144,6 @@ _e_border_eval0(E_Border *bd) bd->theme_shadow = !!edje_object_data_get(o, "shadow"); _e_border_shadow(bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, _e_border_cb_mouse_in, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _e_border_cb_mouse_move, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT, _e_border_cb_mouse_out, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_border_cb_mouse_down, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_border_cb_mouse_up, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd); if (pbg) { if (bd->icon_object) @@ -8175,26 +8168,6 @@ _e_border_eval0(E_Border *bd) * borderless window before its comp win has been set up; * E19 material imo */ - if (o) - { - if (bd->cw && (o == bd->cw->obj)) - { - /* TODO: set these on cw->effect_obj...always. */ - evas_object_event_callback_del_full(o, EVAS_CALLBACK_MOUSE_IN, _e_border_cb_mouse_in, bd); - evas_object_event_callback_del_full(o, EVAS_CALLBACK_MOUSE_MOVE, _e_border_cb_mouse_move, bd); - evas_object_event_callback_del_full(o, EVAS_CALLBACK_MOUSE_OUT, _e_border_cb_mouse_out, bd); - evas_object_event_callback_del_full(o, EVAS_CALLBACK_MOUSE_DOWN, _e_border_cb_mouse_down, bd); - evas_object_event_callback_del_full(o, EVAS_CALLBACK_MOUSE_UP, _e_border_cb_mouse_up, bd); - evas_object_event_callback_del_full(o, EVAS_CALLBACK_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd); - } - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, _e_border_cb_mouse_in, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _e_border_cb_mouse_move, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT, _e_border_cb_mouse_out, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_border_cb_mouse_down, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_border_cb_mouse_up, bd); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd); - } - { // previously calculated Eina_Bool calc = bd->client_inset.calc; @@ -8280,6 +8253,13 @@ _e_border_eval0(E_Border *bd) } _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd); + if (!new_cw) return; + evas_object_event_callback_add(bd->cw->effect_obj, EVAS_CALLBACK_MOUSE_IN, _e_border_cb_mouse_in, bd); + evas_object_event_callback_add(bd->cw->effect_obj, EVAS_CALLBACK_MOUSE_MOVE, _e_border_cb_mouse_move, bd); + evas_object_event_callback_add(bd->cw->effect_obj, EVAS_CALLBACK_MOUSE_OUT, _e_border_cb_mouse_out, bd); + evas_object_event_callback_add(bd->cw->effect_obj, EVAS_CALLBACK_MOUSE_DOWN, _e_border_cb_mouse_down, bd); + evas_object_event_callback_add(bd->cw->effect_obj, EVAS_CALLBACK_MOUSE_UP, _e_border_cb_mouse_up, bd); + evas_object_event_callback_add(bd->cw->effect_obj, EVAS_CALLBACK_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd); } static void diff --git a/src/bin/e_comp.c b/src/bin/e_comp.c index 51cd81995..72bb72133 100644 --- a/src/bin/e_comp.c +++ b/src/bin/e_comp.c @@ -21,6 +21,7 @@ ////////////////////////////////////////////////////////////////////////// static Eina_List *handlers = NULL; +static Eina_List *hooks = NULL; static Eina_List *compositors = NULL; static Eina_Hash *windows = NULL; static Eina_Hash *borders = NULL; @@ -3399,36 +3400,33 @@ _e_comp_zonech(void *data EINA_UNUSED, int type EINA_UNUSED, EINA_UNUSED void *e return ECORE_CALLBACK_PASS_ON; } -static Eina_Bool -_e_comp_bd_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) +static void +_e_comp_bd_add(void *data EINA_UNUSED, void *ev) { - E_Event_Border_Add *ev = event; + E_Border *bd = ev; E_Comp_Win *cw; E_Container *con; int x; - cw = ev->border->cw; - if (!cw) + if (bd->cw) return; + cw = _e_comp_win_find(bd->win); + if (cw) { - cw = _e_comp_win_find(ev->border->win); - if (cw) - { - _e_comp_win_bd_setup(cw, ev->border); - evas_object_data_set(cw->shobj, "border", cw->bd); - evas_object_data_set(cw->effect_obj, "border", cw->bd); + _e_comp_win_bd_setup(cw, bd); + evas_object_data_set(cw->shobj, "border", cw->bd); + evas_object_data_set(cw->effect_obj, "border", cw->bd); #ifdef BORDER_ZOOMAPS - evas_object_name_set(cw->zoomobj, "cw->zoomobj::BORDER"); + evas_object_name_set(cw->zoomobj, "cw->zoomobj::BORDER"); #endif - evas_object_name_set(cw->shobj, "cw->shobj::BORDER"); - evas_object_name_set(cw->effect_obj, "cw->effect_obj::BORDER"); - e_comp_win_reshadow(cw); - } - else - cw = _e_comp_win_add(e_comp_get(ev->border), ev->border->win, ev->border); + evas_object_name_set(cw->shobj, "cw->shobj::BORDER"); + evas_object_name_set(cw->effect_obj, "cw->effect_obj::BORDER"); + e_comp_win_reshadow(cw); } - _e_comp_win_configure(cw, ev->border->x, ev->border->y, - ev->border->w, ev->border->h, - ev->border->client.initial_attributes.border); + else + cw = _e_comp_win_add(e_comp_get(bd), bd->win, bd); + _e_comp_win_configure(cw, bd->x, bd->y, + bd->w, bd->h, + bd->client.initial_attributes.border); if (cw->shape) cw->shape->comp_win = cw; con = cw->bd->zone->container; /* we previously ignored potential stacking requests before the border setup, @@ -3436,7 +3434,7 @@ _e_comp_bd_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) for (x = 0; x < E_CONTAINER_LAYER_COUNT; x++) { Eina_List *l; - E_Border *bd; + E_Border *bd2; E_Comp_Win *cw2; if (!con->layers[x].clients) continue; @@ -3444,8 +3442,8 @@ _e_comp_bd_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) if (!l) continue; if (l->prev) { - bd = eina_list_data_get(l->prev); - cw2 = _e_comp_win_find(bd->win); + bd2 = eina_list_data_get(l->prev); + cw2 = _e_comp_win_find(bd2->win); if (cw2) { _e_comp_win_raise_above(cw, cw2); @@ -3454,8 +3452,8 @@ _e_comp_bd_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) } if (l->next) { - bd = eina_list_data_get(l->next); - cw2 = _e_comp_win_find(bd->win); + bd2 = eina_list_data_get(l->next); + cw2 = _e_comp_win_find(bd2->win); if (cw2) { _e_comp_win_lower_below(cw, cw2); @@ -3470,7 +3468,6 @@ _e_comp_bd_add(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) //{ //_e_comp_win_show(cw); //} - return ECORE_CALLBACK_PASS_ON; } static Eina_Bool @@ -4881,7 +4878,7 @@ e_comp_init(void) E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _e_comp_zonech, NULL); E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _e_comp_zonech, NULL); - E_LIST_HANDLER_APPEND(handlers, E_EVENT_BORDER_ADD, _e_comp_bd_add, NULL); + hooks = eina_list_append(hooks, e_border_hook_add(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, _e_comp_bd_add, NULL)); E_LIST_HANDLER_APPEND(handlers, E_EVENT_BORDER_REMOVE, _e_comp_bd_del, NULL); E_LIST_HANDLER_APPEND(handlers, E_EVENT_BORDER_SHOW, _e_comp_bd_show, NULL); E_LIST_HANDLER_APPEND(handlers, E_EVENT_BORDER_HIDE, _e_comp_bd_hide, NULL); @@ -4969,6 +4966,7 @@ e_comp_shutdown(void) E_FREE_LIST(compositors, _e_comp_del); E_FREE_LIST(handlers, ecore_event_handler_del); E_FREE_LIST(actions, e_object_del); + E_FREE_LIST(hooks, e_border_hook_del); #ifdef HAVE_WAYLAND_CLIENTS e_comp_wl_shutdown();