Fix longstanding focus bug with mouse (not sloppy) focus mode with popup

2006-10-01  Elijah Newren  <newren gmail com>

	Fix longstanding focus bug with mouse (not sloppy) focus mode with
	popup override-redirect windows, particularly mozilla and
	firefox's location bar autocompletion.  #357695.

	* src/display.c (event_callback -- EnterNotify & LeaveNotify events):
	for mouse focus, defocus the focused window when the mouse enters
	the desktop window rather than when the mouse leaves the focused
	window.

	* doc/how-to-get-focus-right.txt:
	update for the slightly nuanced definition of mouse focus (people
	without a DESKTOP window like nautilus get sloppy focus behavior
	now)
This commit is contained in:
Elijah Newren 2006-10-01 18:10:24 +00:00 committed by Elijah Newren
parent 3cca3f3ee9
commit b694312f1c
3 changed files with 59 additions and 51 deletions

View File

@ -1,3 +1,19 @@
2006-10-01 Elijah Newren <newren gmail com>
Fix longstanding focus bug with mouse (not sloppy) focus mode with
popup override-redirect windows, particularly mozilla and
firefox's location bar autocompletion. #357695.
* src/display.c (event_callback -- EnterNotify & LeaveNotify events):
for mouse focus, defocus the focused window when the mouse enters
the desktop window rather than when the mouse leaves the focused
window.
* doc/how-to-get-focus-right.txt:
update for the slightly nuanced definition of mouse focus (people
without a DESKTOP window like nautilus get sloppy focus behavior
now)
2006-09-27 Elijah Newren <newren gmail com> 2006-09-27 Elijah Newren <newren gmail com>
* src/menu.c (var menuitems): Patch from Bruno Boaventura to add * src/menu.c (var menuitems): Patch from Bruno Boaventura to add

View File

@ -9,7 +9,8 @@ basics are easy:
Focus method Behavior Focus method Behavior
click When a user clicks on a window, focus it click When a user clicks on a window, focus it
sloppy When an EnterNotify is received, focus the window sloppy When an EnterNotify is received, focus the window
mouse Same as sloppy, but also defocus on LeaveNotify mouse Same as sloppy, but also defocus when mouse enters DESKTOP
window
Note that these choices (along with the choice that clicking on a Note that these choices (along with the choice that clicking on a
window raises it for the click focus method) introduces the following window raises it for the click focus method) introduces the following
@ -20,8 +21,9 @@ Focus method Invariant
sloppy If the mouse is in a window, then it is focused; if the sloppy If the mouse is in a window, then it is focused; if the
mouse is not in a window, then the most recently used mouse is not in a window, then the most recently used
window is focused. window is focused.
mouse If the mouse is in a window, then it is focused; otherwise,
the designated "no_focus_window" is focused mouse If the mouse is in a non-DESKTOP window, then it is focused;
otherwise, the designated "no_focus_window" is focused
However, there are a number of cases where the current focus window However, there are a number of cases where the current focus window
becomes invalid and another should be chosen. Some examples are when becomes invalid and another should be chosen. Some examples are when
@ -34,8 +36,10 @@ Focus method Behavior
on top) on top)
sloppy Focus the window containing the pointer if there is such sloppy Focus the window containing the pointer if there is such
a window, otherwise focus the most recently used window. a window, otherwise focus the most recently used window.
mouse Focus the window containing the pointer if there is one,
otherwise focus the designated "no_focus_window". mouse Focus the non-DESKTOP window containing the pointer if
there is one, otherwise focus the designated
"no_focus_window".
Note that "most recently used window", as used here, has a slightly Note that "most recently used window", as used here, has a slightly
different connotation than "most recent to have keyboard focus". This different connotation than "most recent to have keyboard focus". This
@ -123,6 +127,7 @@ To read more about the bugs that inspired these choices:
- Mousenav vs. Keynav in mouse and sloppy focus modes - Mousenav vs. Keynav in mouse and sloppy focus modes
http://bugzilla.gnome.org/show_bug.cgi?id=167545 http://bugzilla.gnome.org/show_bug.cgi?id=167545
http://bugzilla.gnome.org/show_bug.cgi?id=101190 http://bugzilla.gnome.org/show_bug.cgi?id=101190
http://bugzilla.gnome.org/show_bug.cgi?id=357695
- Not focusing panels - Not focusing panels
http://bugzilla.gnome.org/show_bug.cgi?id=160470 http://bugzilla.gnome.org/show_bug.cgi?id=160470
http://bugzilla.gnome.org/show_bug.cgi?id=120100 http://bugzilla.gnome.org/show_bug.cgi?id=120100

View File

@ -1847,6 +1847,7 @@ event_callback (XEvent *event,
{ {
case META_FOCUS_MODE_SLOPPY: case META_FOCUS_MODE_SLOPPY:
case META_FOCUS_MODE_MOUSE: case META_FOCUS_MODE_MOUSE:
display->mouse_mode = TRUE;
if (window->type != META_WINDOW_DOCK && if (window->type != META_WINDOW_DOCK &&
window->type != META_WINDOW_DESKTOP) window->type != META_WINDOW_DESKTOP)
{ {
@ -1858,21 +1859,41 @@ event_callback (XEvent *event,
event->xany.serial, event->xany.serial,
event->xcrossing.time); event->xcrossing.time);
display->mouse_mode = TRUE;
meta_window_focus (window, event->xcrossing.time); meta_window_focus (window, event->xcrossing.time);
/* stop ignoring stuff */ /* stop ignoring stuff */
reset_ignores (display); reset_ignores (display);
if (meta_prefs_get_auto_raise ()) if (meta_prefs_get_auto_raise ())
{ {
meta_display_queue_autoraise_callback (display, window); meta_display_queue_autoraise_callback (display, window);
} }
else else
{ {
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"Auto raise is disabled\n"); "Auto raise is disabled\n");
} }
}
/* In mouse focus mode, we defocus when the mouse *enters*
* the DESKTOP window, instead of defocusing on LeaveNotify.
* This is because having the mouse enter override-redirect
* child windows unfortunately causes LeaveNotify events that
* we can't distinguish from the mouse actually leaving the
* toplevel window as we expect. But, since we filter out
* EnterNotify events on override-redirect windows, this
* alternative mechanism works great.
*/
if (window->type == META_WINDOW_DESKTOP &&
meta_prefs_get_focus_mode() == META_FOCUS_MODE_MOUSE &&
display->expected_focus_window != NULL)
{
meta_topic (META_DEBUG_FOCUS,
"Unsetting focus from %s due to mouse entering "
"the DESKTOP window\n",
display->expected_focus_window->desc);
meta_display_focus_the_no_focus_window (display,
window->screen,
event->xcrossing.time);
} }
break; break;
case META_FOCUS_MODE_CLICK: case META_FOCUS_MODE_CLICK:
@ -1890,40 +1911,6 @@ event_callback (XEvent *event,
meta_window_handle_mouse_grab_op_event (window, event); meta_window_handle_mouse_grab_op_event (window, event);
else if (window != NULL) else if (window != NULL)
{ {
switch (meta_prefs_get_focus_mode ())
{
case META_FOCUS_MODE_MOUSE:
if ((window->frame == NULL || frame_was_receiver) &&
event->xcrossing.mode != NotifyGrab &&
event->xcrossing.mode != NotifyUngrab &&
event->xcrossing.detail != NotifyInferior &&
meta_display_focus_sentinel_clear (display))
{
if (window == display->expected_focus_window)
{
meta_topic (META_DEBUG_FOCUS,
"Unsetting focus from %s due to LeaveNotify\n",
window->desc);
meta_display_focus_the_no_focus_window (display,
window->screen,
event->xcrossing.time);
}
if (window->type != META_WINDOW_DOCK &&
window->type != META_WINDOW_DESKTOP)
{
meta_topic (META_DEBUG_FOCUS,
"Setting display->mouse_mode to TRUE due to "
"LeaveNotify at time %lu.\n",
event->xcrossing.time);
display->mouse_mode = TRUE;
}
}
break;
case META_FOCUS_MODE_SLOPPY:
case META_FOCUS_MODE_CLICK:
break;
}
if (window->type == META_WINDOW_DOCK && if (window->type == META_WINDOW_DOCK &&
event->xcrossing.mode != NotifyGrab && event->xcrossing.mode != NotifyGrab &&
event->xcrossing.mode != NotifyUngrab && event->xcrossing.mode != NotifyUngrab &&