mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 21:34:09 +00:00
CVS2003-05-29 Rob Adams <robadams@ucla.edu>
CVS2003-05-29 Rob Adams <robadams@ucla.edu> Use a new property _METACITY_SENTINEL to eliminate a race condition that causes focus to behave badly with sloppy/mouse focus when lots of windows are mapped/unmapped, such as with a workspace switch. The EnterNotify events on a display are ignored until the PropertyNotify sent after all the window maps is received. This is a fix for #110970. * src/display.[ch]: New _METACITY_SENTINEL atom. (event_callback): ignore EnterNotify if the sentinel isn't clear, and decrement the sentinel counter when the PropertyNotify is received. (meta_display_increment_focus_sentinel): new function. Increments the sentinel counter and updates the property on a root window on this display. (meta_display_decrement_focus_sentinel): Decrement the sentinel counter. (meta_display_focus_sentinel_clear): returns whether the sentinel counter is zero. * src/window.c (idle_calc_showing): after showing windows, call meta_display_increment_focus_sentinel on each display for windows to be shown. * src/workspace.[ch] (meta_workspace_activate_with_focus): new function activates a workspace and focuses a particular window after the workspace is activated. (meta_workspace_activate): now just a wrapper for meta_workspace_activate_with_focus * src/keybindings.c: use new meta_workspace_activate_with_focus function to ensure that focus will follow the focused window through the workspace switch. : ----------------------------------------------------------------------
This commit is contained in:
parent
903f3d7e6e
commit
3edad8599c
35
ChangeLog
35
ChangeLog
@ -1,3 +1,38 @@
|
|||||||
|
2003-05-29 Rob Adams <robadams@ucla.edu>
|
||||||
|
|
||||||
|
Use a new property _METACITY_SENTINEL to eliminate a race
|
||||||
|
condition that causes focus to behave badly with sloppy/mouse
|
||||||
|
focus when lots of windows are mapped/unmapped, such as with a
|
||||||
|
workspace switch. The EnterNotify events on a display are ignored
|
||||||
|
until the PropertyNotify sent after all the window maps is
|
||||||
|
received. This is a fix for #110970.
|
||||||
|
|
||||||
|
* src/display.[ch]: New _METACITY_SENTINEL atom.
|
||||||
|
(event_callback): ignore EnterNotify if the sentinel isn't clear,
|
||||||
|
and decrement the sentinel counter when the PropertyNotify is
|
||||||
|
received.
|
||||||
|
(meta_display_increment_focus_sentinel): new function. Increments
|
||||||
|
the sentinel counter and updates the property on a root window on
|
||||||
|
this display.
|
||||||
|
(meta_display_decrement_focus_sentinel): Decrement the sentinel
|
||||||
|
counter.
|
||||||
|
(meta_display_focus_sentinel_clear): returns whether the sentinel
|
||||||
|
counter is zero.
|
||||||
|
|
||||||
|
* src/window.c (idle_calc_showing): after showing windows, call
|
||||||
|
meta_display_increment_focus_sentinel on each display for windows
|
||||||
|
to be shown.
|
||||||
|
|
||||||
|
* src/workspace.[ch] (meta_workspace_activate_with_focus): new
|
||||||
|
function activates a workspace and focuses a particular window
|
||||||
|
after the workspace is activated.
|
||||||
|
(meta_workspace_activate): now just a wrapper for
|
||||||
|
meta_workspace_activate_with_focus
|
||||||
|
|
||||||
|
* src/keybindings.c: use new meta_workspace_activate_with_focus
|
||||||
|
function to ensure that focus will follow the focused window
|
||||||
|
through the workspace switch.
|
||||||
|
|
||||||
2003-05-29 Havoc Pennington <hp@redhat.com>
|
2003-05-29 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* src/theme-parser.c (meta_theme_load): s/int/gsize/ for
|
* src/theme-parser.c (meta_theme_load): s/int/gsize/ for
|
||||||
|
@ -269,7 +269,8 @@ meta_display_open (const char *name)
|
|||||||
"SYNC_COUNTER",
|
"SYNC_COUNTER",
|
||||||
"_GNOME_PANEL_ACTION",
|
"_GNOME_PANEL_ACTION",
|
||||||
"_GNOME_PANEL_ACTION_MAIN_MENU",
|
"_GNOME_PANEL_ACTION_MAIN_MENU",
|
||||||
"_GNOME_PANEL_ACTION_RUN_DIALOG"
|
"_GNOME_PANEL_ACTION_RUN_DIALOG",
|
||||||
|
"_METACITY_SENTINEL"
|
||||||
};
|
};
|
||||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
|
|
||||||
@ -416,6 +417,7 @@ meta_display_open (const char *name)
|
|||||||
display->atom_gnome_panel_action = atoms[81];
|
display->atom_gnome_panel_action = atoms[81];
|
||||||
display->atom_gnome_panel_action_main_menu = atoms[82];
|
display->atom_gnome_panel_action_main_menu = atoms[82];
|
||||||
display->atom_gnome_panel_action_run_dialog = atoms[83];
|
display->atom_gnome_panel_action_run_dialog = atoms[83];
|
||||||
|
display->atom_metacity_sentinel = atoms[84];
|
||||||
|
|
||||||
display->prop_hooks = NULL;
|
display->prop_hooks = NULL;
|
||||||
meta_display_init_window_prop_hooks (display);
|
meta_display_init_window_prop_hooks (display);
|
||||||
@ -473,6 +475,7 @@ meta_display_open (const char *name)
|
|||||||
display->ungrab_should_not_cause_focus_window = None;
|
display->ungrab_should_not_cause_focus_window = None;
|
||||||
|
|
||||||
display->current_time = CurrentTime;
|
display->current_time = CurrentTime;
|
||||||
|
display->sentinel_counter = 0;
|
||||||
|
|
||||||
display->grab_op = META_GRAB_OP_NONE;
|
display->grab_op = META_GRAB_OP_NONE;
|
||||||
display->grab_window = NULL;
|
display->grab_window = NULL;
|
||||||
@ -1434,7 +1437,8 @@ event_callback (XEvent *event,
|
|||||||
meta_window_handle_mouse_grab_op_event (window, event);
|
meta_window_handle_mouse_grab_op_event (window, event);
|
||||||
/* do this even if window->has_focus to avoid races */
|
/* do this even if window->has_focus to avoid races */
|
||||||
else if (window && !serial_is_ignored (display, event->xany.serial) &&
|
else if (window && !serial_is_ignored (display, event->xany.serial) &&
|
||||||
event->xcrossing.detail != NotifyInferior)
|
event->xcrossing.detail != NotifyInferior &&
|
||||||
|
meta_display_focus_sentinel_clear (display))
|
||||||
{
|
{
|
||||||
switch (meta_prefs_get_focus_mode ())
|
switch (meta_prefs_get_focus_mode ())
|
||||||
{
|
{
|
||||||
@ -1749,6 +1753,16 @@ event_callback (XEvent *event,
|
|||||||
else if (event->xproperty.atom ==
|
else if (event->xproperty.atom ==
|
||||||
display->atom_net_desktop_names)
|
display->atom_net_desktop_names)
|
||||||
meta_screen_update_workspace_names (screen);
|
meta_screen_update_workspace_names (screen);
|
||||||
|
|
||||||
|
/* we just use this property as a sentinel to avoid
|
||||||
|
* certain race conditions. See the comment for the
|
||||||
|
* sentinel_counter variable declaration in display.h
|
||||||
|
*/
|
||||||
|
if (event->xproperty.atom ==
|
||||||
|
display->atom_metacity_sentinel)
|
||||||
|
{
|
||||||
|
meta_display_decrement_focus_sentinel (display);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3996,3 +4010,34 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
|
meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_increment_focus_sentinel (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
unsigned long data[1];
|
||||||
|
|
||||||
|
data[0] = meta_display_get_current_time (display);
|
||||||
|
|
||||||
|
XChangeProperty (display->xdisplay,
|
||||||
|
((MetaScreen*) display->screens->data)->xroot,
|
||||||
|
display->atom_metacity_sentinel,
|
||||||
|
XA_CARDINAL,
|
||||||
|
32, PropModeReplace, (guchar*) data, 1);
|
||||||
|
|
||||||
|
display->sentinel_counter += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_decrement_focus_sentinel (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
display->sentinel_counter -= 1;
|
||||||
|
|
||||||
|
if (display->sentinel_counter < 0)
|
||||||
|
display->sentinel_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_display_focus_sentinel_clear (MetaDisplay *display)
|
||||||
|
{
|
||||||
|
return (display->sentinel_counter == 0);
|
||||||
|
}
|
||||||
|
@ -172,6 +172,7 @@ struct _MetaDisplay
|
|||||||
Atom atom_gnome_panel_action;
|
Atom atom_gnome_panel_action;
|
||||||
Atom atom_gnome_panel_action_main_menu;
|
Atom atom_gnome_panel_action_main_menu;
|
||||||
Atom atom_gnome_panel_action_run_dialog;
|
Atom atom_gnome_panel_action_run_dialog;
|
||||||
|
Atom atom_metacity_sentinel;
|
||||||
|
|
||||||
/* This is the actual window from focus events,
|
/* This is the actual window from focus events,
|
||||||
* not the one we last set
|
* not the one we last set
|
||||||
@ -248,6 +249,12 @@ struct _MetaDisplay
|
|||||||
MetaResizePopup *grab_resize_popup;
|
MetaResizePopup *grab_resize_popup;
|
||||||
GTimeVal grab_last_moveresize_time;
|
GTimeVal grab_last_moveresize_time;
|
||||||
Time grab_motion_notify_time;
|
Time grab_motion_notify_time;
|
||||||
|
|
||||||
|
/* we use property updates as sentinels for certain window focus events
|
||||||
|
* to avoid some race conditions on EnterNotify events
|
||||||
|
*/
|
||||||
|
int sentinel_counter;
|
||||||
|
|
||||||
#ifdef HAVE_XKB
|
#ifdef HAVE_XKB
|
||||||
int xkb_base_event_type;
|
int xkb_base_event_type;
|
||||||
#endif
|
#endif
|
||||||
@ -439,4 +446,8 @@ void meta_display_devirtualize_modifiers (MetaDisplay *display,
|
|||||||
MetaVirtualModifier modifiers,
|
MetaVirtualModifier modifiers,
|
||||||
unsigned int *mask);
|
unsigned int *mask);
|
||||||
|
|
||||||
|
void meta_display_increment_focus_sentinel (MetaDisplay *display);
|
||||||
|
void meta_display_decrement_focus_sentinel (MetaDisplay *display);
|
||||||
|
gboolean meta_display_focus_sentinel_clear (MetaDisplay *display);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3022,7 +3022,7 @@ do_handle_move_to_workspace (MetaDisplay *display,
|
|||||||
/* Activate second, so the window is never unmapped */
|
/* Activate second, so the window is never unmapped */
|
||||||
meta_window_change_workspace (window, workspace);
|
meta_window_change_workspace (window, workspace);
|
||||||
if (flip)
|
if (flip)
|
||||||
meta_workspace_activate (workspace);
|
meta_workspace_activate_with_focus (workspace, window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
21
src/window.c
21
src/window.c
@ -1338,6 +1338,7 @@ idle_calc_showing (gpointer data)
|
|||||||
GSList *should_show;
|
GSList *should_show;
|
||||||
GSList *should_hide;
|
GSList *should_hide;
|
||||||
GSList *unplaced;
|
GSList *unplaced;
|
||||||
|
GSList *displays;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WINDOW_STATE,
|
meta_topic (META_DEBUG_WINDOW_STATE,
|
||||||
"Clearing the calc_showing queue\n");
|
"Clearing the calc_showing queue\n");
|
||||||
@ -1361,6 +1362,7 @@ idle_calc_showing (gpointer data)
|
|||||||
should_show = NULL;
|
should_show = NULL;
|
||||||
should_hide = NULL;
|
should_hide = NULL;
|
||||||
unplaced = NULL;
|
unplaced = NULL;
|
||||||
|
displays = NULL;
|
||||||
|
|
||||||
tmp = copy;
|
tmp = copy;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
@ -1439,11 +1441,30 @@ idle_calc_showing (gpointer data)
|
|||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* for all displays used in the queue, set a sentinel property on
|
||||||
|
* the root window so that we can ignore EnterNotify events that
|
||||||
|
* occur before the window maps occur. This avoids a race
|
||||||
|
* condition. */
|
||||||
|
tmp = should_show;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaWindow *window = tmp->data;
|
||||||
|
|
||||||
|
if (g_slist_find (displays, window->display) == NULL)
|
||||||
|
{
|
||||||
|
displays = g_slist_prepend (displays, window->display);
|
||||||
|
meta_display_increment_focus_sentinel (window->display);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
g_slist_free (copy);
|
g_slist_free (copy);
|
||||||
|
|
||||||
g_slist_free (unplaced);
|
g_slist_free (unplaced);
|
||||||
g_slist_free (should_show);
|
g_slist_free (should_show);
|
||||||
g_slist_free (should_hide);
|
g_slist_free (should_hide);
|
||||||
|
g_slist_free (displays);
|
||||||
|
|
||||||
destroying_windows_disallowed -= 1;
|
destroying_windows_disallowed -= 1;
|
||||||
|
|
||||||
|
@ -196,7 +196,8 @@ meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_workspace_activate (MetaWorkspace *workspace)
|
meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||||
|
MetaWindow *focus_this)
|
||||||
{
|
{
|
||||||
MetaWorkspace *old;
|
MetaWorkspace *old;
|
||||||
|
|
||||||
@ -218,8 +219,24 @@ meta_workspace_activate (MetaWorkspace *workspace)
|
|||||||
meta_workspace_queue_calc_showing (old);
|
meta_workspace_queue_calc_showing (old);
|
||||||
meta_workspace_queue_calc_showing (workspace);
|
meta_workspace_queue_calc_showing (workspace);
|
||||||
|
|
||||||
|
if (focus_this)
|
||||||
|
{
|
||||||
|
meta_window_focus (focus_this,
|
||||||
|
meta_display_get_current_time (focus_this->display));
|
||||||
|
meta_window_raise (focus_this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
|
meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
|
||||||
meta_screen_focus_default_window (workspace->screen, NULL);
|
meta_screen_focus_default_window (workspace->screen, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_activate (MetaWorkspace *workspace)
|
||||||
|
{
|
||||||
|
meta_workspace_activate_with_focus (workspace,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -58,6 +58,8 @@ void meta_workspace_relocate_windows (MetaWorkspace *workspace,
|
|||||||
/* don't confuse with meta_window_visible_on_workspace() */
|
/* don't confuse with meta_window_visible_on_workspace() */
|
||||||
gboolean meta_workspace_contains_window (MetaWorkspace *workspace,
|
gboolean meta_workspace_contains_window (MetaWorkspace *workspace,
|
||||||
MetaWindow *window);
|
MetaWindow *window);
|
||||||
|
void meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||||
|
MetaWindow *focus_this);
|
||||||
void meta_workspace_activate (MetaWorkspace *workspace);
|
void meta_workspace_activate (MetaWorkspace *workspace);
|
||||||
int meta_workspace_index (MetaWorkspace *workspace);
|
int meta_workspace_index (MetaWorkspace *workspace);
|
||||||
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
|
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user