diff --git a/ChangeLog b/ChangeLog index 4666cba3c..94eee121d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2004-10-04 Elijah Newren + + Fix a variety of issues with autoraise (#134206) + + * src/display.h: (struct _MetaDisplay): add an autoraise_window + parameter + + * src/display.[hc] (meta_display_focus_the_no_focus_window): new + function, (meta_display_queue_autoraise_callback): new function, + (meta_display_remove_autoraise_callback): new function + + * src/display.c (meta_display_open): intialize + display->autoraise_window too, (meta_display_close): remove any + pending autoraise callback, (window_raise_with_delay_callback): + clear out auto_raise->display->autoraise_window too, + (event_callback): call meta_display_queue_autoraise_callback + instead of having the code inline, call + meta_display_focus_the_no_focus_window to handle focusing that + window + + * src/window.c (meta_window_focus): If there's a window with an + autoraise timeout that isn't the window being focused, remove the + autoraise timeout + + * src/workspace.c (meta_workspace_focus_default_window): If no + autoraise timeout is queued for the given window then queue one + now, call meta_display_focus_the_no_focus_window to handle + focusing that window, (meta_workspace_focus_mru_window): call + meta_display_focus_the_no_focus_window to handle focusing that + window + 2004-10-04 Elijah Newren * src/display.c (event_callback): When no window becomes focused, diff --git a/src/display.c b/src/display.c index 81cd81b65..f4f82a0ee 100644 --- a/src/display.c +++ b/src/display.c @@ -328,6 +328,7 @@ meta_display_open (const char *name) display->pending_pings = NULL; display->autoraise_timeout_id = 0; + display->autoraise_window = NULL; display->focus_window = NULL; display->previously_focused_window = NULL; display->expected_focus_window = NULL; @@ -780,11 +781,7 @@ meta_display_close (MetaDisplay *display) meta_prefs_remove_listener (prefs_changed_callback, display); - if (display->autoraise_timeout_id != 0) - { - g_source_remove (display->autoraise_timeout_id); - display->autoraise_timeout_id = 0; - } + meta_display_remove_autoraise_callback (display); #ifdef USE_GDK_DISPLAY /* Stop caring about events */ @@ -1193,6 +1190,7 @@ window_raise_with_delay_callback (void *data) auto_raise->xwindow); auto_raise->display->autoraise_timeout_id = 0; + auto_raise->display->autoraise_window = NULL; window = meta_display_lookup_x_window (auto_raise->display, auto_raise->xwindow); @@ -1229,6 +1227,33 @@ window_raise_with_delay_callback (void *data) return FALSE; } +void +meta_display_queue_autoraise_callback (MetaDisplay *display, + MetaWindow *window) +{ + MetaAutoRaiseData *auto_raise_data; + + meta_topic (META_DEBUG_FOCUS, + "Queuing an autoraise timeout for %s with delay %d\n", + window->desc, + meta_prefs_get_auto_raise_delay ()); + + auto_raise_data = g_new (MetaAutoRaiseData, 1); + auto_raise_data->display = window->display; + auto_raise_data->xwindow = window->xwindow; + + if (display->autoraise_timeout_id != 0) + g_source_remove (display->autoraise_timeout_id); + + display->autoraise_timeout_id = + g_timeout_add_full (G_PRIORITY_DEFAULT, + meta_prefs_get_auto_raise_delay (), + window_raise_with_delay_callback, + auto_raise_data, + g_free); + display->autoraise_window = window; +} + static int double_click_timeout_for_event (MetaDisplay *display, XEvent *event) @@ -1732,26 +1757,7 @@ event_callback (XEvent *event, if (meta_prefs_get_auto_raise ()) { - MetaAutoRaiseData *auto_raise_data; - - meta_topic (META_DEBUG_FOCUS, - "Queuing an autoraise timeout for %s with delay %d\n", - window->desc, - meta_prefs_get_auto_raise_delay ()); - - auto_raise_data = g_new (MetaAutoRaiseData, 1); - auto_raise_data->display = window->display; - auto_raise_data->xwindow = window->xwindow; - - if (display->autoraise_timeout_id != 0) - g_source_remove (display->autoraise_timeout_id); - - display->autoraise_timeout_id = - g_timeout_add_full (G_PRIORITY_DEFAULT, - meta_prefs_get_auto_raise_delay (), - window_raise_with_delay_callback, - auto_raise_data, - g_free); + meta_display_queue_autoraise_callback (display, window); } else { @@ -1786,10 +1792,8 @@ event_callback (XEvent *event, { meta_verbose ("Unsetting focus from %s due to LeaveNotify\n", window->desc); - XSetInputFocus (display->xdisplay, - display->no_focus_window, - RevertToPointerRoot, - event->xcrossing.time); + meta_display_focus_the_no_focus_window (display, + event->xcrossing.time); } break; case META_FOCUS_MODE_SLOPPY: @@ -4572,3 +4576,25 @@ meta_display_focus_sentinel_clear (MetaDisplay *display) { return (display->sentinel_counter == 0); } + +void +meta_display_focus_the_no_focus_window (MetaDisplay *display, + Time timestamp) +{ + XSetInputFocus (display->xdisplay, + display->no_focus_window, + RevertToPointerRoot, + timestamp); + meta_display_remove_autoraise_callback (display); +} + +void +meta_display_remove_autoraise_callback (MetaDisplay *display) +{ + if (display->autoraise_timeout_id != 0) + { + g_source_remove (display->autoraise_timeout_id); + display->autoraise_timeout_id = 0; + display->autoraise_window = NULL; + } +} diff --git a/src/display.h b/src/display.h index abdb7f0f0..ff40938de 100644 --- a/src/display.h +++ b/src/display.h @@ -233,6 +233,7 @@ struct _MetaDisplay /* Pending autoraise */ guint autoraise_timeout_id; + MetaWindow* autoraise_window; /* Alt+click button grabs */ unsigned int window_grab_modifiers; @@ -485,4 +486,10 @@ void meta_display_increment_focus_sentinel (MetaDisplay *display); void meta_display_decrement_focus_sentinel (MetaDisplay *display); gboolean meta_display_focus_sentinel_clear (MetaDisplay *display); +void meta_display_focus_the_no_focus_window (MetaDisplay *display, + Time timestamp); +void meta_display_queue_autoraise_callback (MetaDisplay *display, + MetaWindow *window); +void meta_display_remove_autoraise_callback (MetaDisplay *display); + #endif diff --git a/src/window.c b/src/window.c index 9bc5e687b..3460f8dec 100644 --- a/src/window.c +++ b/src/window.c @@ -3323,6 +3323,10 @@ meta_window_focus (MetaWindow *window, window->wm_state_demands_attention = FALSE; set_net_wm_state (window); } + + /* Check if there's an autoraise timeout for a different window */ + if (window != window->display->autoraise_window) + meta_display_remove_autoraise_callback (window->display); } static void diff --git a/src/workspace.c b/src/workspace.c index 6b03ce406..3cf55f527 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -830,6 +830,13 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, "Focusing mouse window %s\n", window->desc); meta_window_focus (window, timestamp); } + + if (workspace->screen->display->autoraise_window != window && + meta_prefs_get_auto_raise ()) + { + meta_display_queue_autoraise_callback (workspace->screen->display, + window); + } } else if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_SLOPPY) meta_workspace_focus_mru_window (workspace, not_this_one, timestamp); @@ -838,10 +845,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, meta_topic (META_DEBUG_FOCUS, "Setting focus to no_focus_window, since no valid " "window to focus found.\n"); - XSetInputFocus (workspace->screen->display->xdisplay, - workspace->screen->display->no_focus_window, - RevertToPointerRoot, - timestamp); + meta_display_focus_the_no_focus_window (workspace->screen->display, + timestamp); } } } @@ -891,9 +896,7 @@ meta_workspace_focus_mru_window (MetaWorkspace *workspace, else { meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n"); - XSetInputFocus (workspace->screen->display->xdisplay, - workspace->screen->display->no_focus_window, - RevertToPointerRoot, - timestamp); + meta_display_focus_the_no_focus_window (workspace->screen->display, + timestamp); } }