From c71c21a19decf8ab6e22e0d4ff2c199735ef934f Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sun, 10 Jul 2005 10:48:08 +0000 Subject: [PATCH] and now make sure focus goes to the right place on de-iconfiy and stuff SVN revision: 15709 --- src/bin/e_border.c | 58 ++++++++----------------------------------- src/bin/e_grabinput.c | 43 ++++++++++++++++++++++++++++++++ src/bin/e_grabinput.h | 11 +++++++- 3 files changed, 64 insertions(+), 48 deletions(-) diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 388c06443..c4c1ac48f 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -575,16 +575,11 @@ e_border_hide(E_Border *bd, int manage) _e_border_resize_end(bd); } - if (bd->focused) - { - printf("REMOVe FOCUS!\n"); - e_border_focus_set(bd, 0, 1); - } - if (!bd->need_reparent) { if (bd->focused) - ecore_x_window_focus(bd->zone->container->manager->root); +// ecore_x_window_focus(bd->zone->container->manager->root); + e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE); ecore_x_window_hide(bd->client.win); } e_container_shape_hide(bd->shape); @@ -882,55 +877,22 @@ e_border_focus_set(E_Border *bd, int focus, int set) { if ((!bd->client.icccm.accepts_focus) && (!bd->client.icccm.take_focus)) - { - /* no input */ - } + e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_NO_INPUT); else if ((bd->client.icccm.accepts_focus) && (bd->client.icccm.take_focus)) - { - /* locally active */ -/* this is a problem - basically we ASK the client to TAKE the focus itself - * BUT if a whole stream of events is happening, the client may take the focus - * LATER after we have gone and reset it back to somewhere else, thus it steals - * the focus away from where it should be (due to x being async etc.). no matter - * how nice and ICCCM this is - it's a major design flaw (imho) in ICCCM as it - * becomes nigh impossible for the wm then to re-serialise events and get the - * focus back to where it should be. - * - * example scenario of the bug: - * - * mouse enter window X - * wm set focus to X - * mouse leaves window X - * remove focus from window X - * mouse enters window Y - * wm asks client Y to "take the focus" - * mouse instantly moves back to window X - * wm sets focus on X - * suddenly focus is stolen by client Y as it finally recieved the request and took the focus - * - * now the focus is on Y where it should be on X - */ - ecore_x_window_focus(bd->client.win); - ecore_x_icccm_take_focus_send(bd->client.win, ecore_x_current_time_get()); - } + e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE); else if ((!bd->client.icccm.accepts_focus) && (bd->client.icccm.take_focus)) - { - /* globally active */ - ecore_x_icccm_take_focus_send(bd->client.win, ecore_x_current_time_get()); - } + e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE); else if ((bd->client.icccm.accepts_focus) && (!bd->client.icccm.take_focus)) - { - /* passive */ - ecore_x_window_focus(bd->client.win); - } + e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE); } else { // ecore_x_window_focus(bd->zone->container->manager->root); - ecore_x_window_focus(bd->zone->container->bg_win); +// ecore_x_window_focus(bd->zone->container->bg_win); + e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE); } } if ((bd->focused) && (focused != bd)) @@ -1982,7 +1944,9 @@ _e_border_free(E_Border *bd) } if (focused == bd) { - ecore_x_window_focus(bd->zone->container->manager->root); +// ecore_x_window_focus(bd->zone->container->manager->root); + e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE); + e_hints_active_window_set(bd->zone->container->manager, NULL); focused = NULL; } while (bd->handlers) diff --git a/src/bin/e_grabinput.c b/src/bin/e_grabinput.c index 7969d909d..464a3a472 100644 --- a/src/bin/e_grabinput.c +++ b/src/bin/e_grabinput.c @@ -4,10 +4,13 @@ #include "e.h" /* local subsystem functions */ +static void _e_grabinput_focus(Ecore_X_Window win, E_Focus_Method method); /* local subsystem globals */ Ecore_X_Window grab_mouse_win = 0; Ecore_X_Window grab_key_win = 0; +Ecore_X_Window focus_win = 0; +E_Focus_Method focus_method = E_FOCUS_METHOD_NO_INPUT; /* externally accessible functions */ int @@ -34,6 +37,7 @@ e_grabinput_get(Ecore_X_Window mouse_win, int confine_mouse, Ecore_X_Window key_ { ecore_x_keyboard_ungrab(); grab_key_win = 0; + focus_win = 0; } if (mouse_win) { @@ -62,7 +66,46 @@ e_grabinput_release(Ecore_X_Window mouse_win, Ecore_X_Window key_win) { ecore_x_keyboard_ungrab(); grab_key_win = 0; + if (focus_win != 0) + { + _e_grabinput_focus(focus_win, focus_method); + focus_win = 0; + focus_method = E_FOCUS_METHOD_NO_INPUT; + } } } +void +e_grabinput_focus(Ecore_X_Window win, E_Focus_Method method) +{ + if (grab_key_win != 0) + { + focus_win = win; + focus_method = method; + } + else + _e_grabinput_focus(win, method); +} + /* local subsystem functions */ +static void +_e_grabinput_focus(Ecore_X_Window win, E_Focus_Method method) +{ + switch (method) + { + case E_FOCUS_METHOD_NO_INPUT: + break; + case E_FOCUS_METHOD_LOCALLY_ACTIVE: + ecore_x_window_focus(win); + ecore_x_icccm_take_focus_send(win, ecore_x_current_time_get()); + break; + case E_FOCUS_METHOD_GLOBALLY_ACTIVE: + ecore_x_icccm_take_focus_send(win, ecore_x_current_time_get()); + break; + case E_FOCUS_METHOD_PASSIVE: + ecore_x_window_focus(win); + break; + default: + break; + } +} diff --git a/src/bin/e_grabinput.h b/src/bin/e_grabinput.h index 57defac21..f7344c234 100644 --- a/src/bin/e_grabinput.h +++ b/src/bin/e_grabinput.h @@ -3,6 +3,14 @@ */ #ifdef E_TYPEDEFS +typedef enum _E_Focus_Method +{ + E_FOCUS_METHOD_NO_INPUT, + E_FOCUS_METHOD_LOCALLY_ACTIVE, + E_FOCUS_METHOD_GLOBALLY_ACTIVE, + E_FOCUS_METHOD_PASSIVE +} E_Focus_Method; + #else #ifndef E_GRABINPUT_H #define E_GRABINPUT_H @@ -11,6 +19,7 @@ EAPI int e_grabinput_init(void); EAPI int e_grabinput_shutdown(void); EAPI void e_grabinput_get(Ecore_X_Window mouse_win, int confine_mouse, Ecore_X_Window key_win); EAPI void e_grabinput_release(Ecore_X_Window mouse_win, Ecore_X_Window key_win); - +EAPI void e_grabinput_focus(Ecore_X_Window win, E_Focus_Method method); + #endif #endif