and now make sure focus goes to the right place on de-iconfiy and stuff

SVN revision: 15709
This commit is contained in:
Carsten Haitzler 2005-07-10 10:48:08 +00:00
parent 926d3ae86e
commit c71c21a19d
3 changed files with 64 additions and 48 deletions

View File

@ -575,16 +575,11 @@ e_border_hide(E_Border *bd, int manage)
_e_border_resize_end(bd); _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->need_reparent)
{ {
if (bd->focused) 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); ecore_x_window_hide(bd->client.win);
} }
e_container_shape_hide(bd->shape); 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) && if ((!bd->client.icccm.accepts_focus) &&
(!bd->client.icccm.take_focus)) (!bd->client.icccm.take_focus))
{ e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_NO_INPUT);
/* no input */
}
else if ((bd->client.icccm.accepts_focus) && else if ((bd->client.icccm.accepts_focus) &&
(bd->client.icccm.take_focus)) (bd->client.icccm.take_focus))
{ e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
/* 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());
}
else if ((!bd->client.icccm.accepts_focus) && else if ((!bd->client.icccm.accepts_focus) &&
(bd->client.icccm.take_focus)) (bd->client.icccm.take_focus))
{ e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
/* globally active */
ecore_x_icccm_take_focus_send(bd->client.win, ecore_x_current_time_get());
}
else if ((bd->client.icccm.accepts_focus) && else if ((bd->client.icccm.accepts_focus) &&
(!bd->client.icccm.take_focus)) (!bd->client.icccm.take_focus))
{ e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
/* passive */
ecore_x_window_focus(bd->client.win);
}
} }
else else
{ {
// ecore_x_window_focus(bd->zone->container->manager->root); // 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)) if ((bd->focused) && (focused != bd))
@ -1982,7 +1944,9 @@ _e_border_free(E_Border *bd)
} }
if (focused == 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; focused = NULL;
} }
while (bd->handlers) while (bd->handlers)

View File

@ -4,10 +4,13 @@
#include "e.h" #include "e.h"
/* local subsystem functions */ /* local subsystem functions */
static void _e_grabinput_focus(Ecore_X_Window win, E_Focus_Method method);
/* local subsystem globals */ /* local subsystem globals */
Ecore_X_Window grab_mouse_win = 0; Ecore_X_Window grab_mouse_win = 0;
Ecore_X_Window grab_key_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 */ /* externally accessible functions */
int int
@ -34,6 +37,7 @@ e_grabinput_get(Ecore_X_Window mouse_win, int confine_mouse, Ecore_X_Window key_
{ {
ecore_x_keyboard_ungrab(); ecore_x_keyboard_ungrab();
grab_key_win = 0; grab_key_win = 0;
focus_win = 0;
} }
if (mouse_win) if (mouse_win)
{ {
@ -62,7 +66,46 @@ e_grabinput_release(Ecore_X_Window mouse_win, Ecore_X_Window key_win)
{ {
ecore_x_keyboard_ungrab(); ecore_x_keyboard_ungrab();
grab_key_win = 0; 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 */ /* 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;
}
}

View File

@ -3,6 +3,14 @@
*/ */
#ifdef E_TYPEDEFS #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 #else
#ifndef E_GRABINPUT_H #ifndef E_GRABINPUT_H
#define E_GRABINPUT_H #define E_GRABINPUT_H
@ -11,6 +19,7 @@ EAPI int e_grabinput_init(void);
EAPI int e_grabinput_shutdown(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_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_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
#endif #endif