From 11089cb8245b3cd47bcc5bb11b730a6e80cc62cd Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 12 Mar 2002 04:34:17 +0000 Subject: [PATCH] use new functions 2002-03-11 Havoc Pennington * src/keybindings.c: use new functions * src/display.c (meta_display_get_tab_next): (meta_display_get_tab_list): new tab order functions using MRU list instead of map order * src/window.c (meta_window_notify_focus): maintain focus MRU list * src/display.h (struct _MetaDisplay): Keep an MRU list of windows. --- ChangeLog | 13 ++++ src/display.c | 157 +++++++++++++++++++++++++++++++++++++++++++++- src/display.h | 14 ++++- src/keybindings.c | 51 ++++++++------- src/screen.c | 6 +- src/stack.c | 12 ++-- src/window.c | 40 +++++------- src/window.h | 3 + 8 files changed, 237 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56a948f9a..9c0b55b01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2002-03-11 Havoc Pennington + + * src/keybindings.c: use new functions + + * src/display.c (meta_display_get_tab_next): + (meta_display_get_tab_list): new tab order functions using + MRU list instead of map order + + * src/window.c (meta_window_notify_focus): maintain focus MRU list + + * src/display.h (struct _MetaDisplay): Keep an MRU list of + windows. + 2002-03-10 Havoc Pennington * src/display.c (event_callback): support _NET_NUMBER_OF_DESKTOPS diff --git a/src/display.c b/src/display.c index bf6c4a554..28d45f45a 100644 --- a/src/display.c +++ b/src/display.c @@ -240,7 +240,7 @@ meta_display_open (const char *name) display->pending_pings = NULL; display->focus_window = NULL; - display->prev_focus_window = NULL; + display->mru_list = NULL; display->showing_desktop = FALSE; @@ -1509,7 +1509,7 @@ meta_event_mode_to_string (int m) return mode; } -const char* +static const char* stack_mode_to_string (int mode) { switch (mode) @@ -1654,7 +1654,7 @@ meta_spew_event (MetaDisplay *display, break; case ConfigureRequest: name = "ConfigureRequest"; - extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %lx %s", + extra = g_strdup_printf ("parent: 0x%lx window: 0x%lx x: %d %sy: %d %sw: %d %sh: %d %sborder: %d %sabove: %lx %sstackmode: %s %s", event->xconfigurerequest.parent, event->xconfigurerequest.window, event->xconfigurerequest.x, @@ -2506,3 +2506,154 @@ meta_display_window_has_pending_pings (MetaDisplay *display, return FALSE; } +static MetaWindow* +find_tab_forward (MetaDisplay *display, + MetaWorkspace *workspace, + GList *start) +{ + GList *tmp; + + g_return_val_if_fail (start != NULL, NULL); + + tmp = start->next; + while (tmp != NULL) + { + MetaWindow *window = tmp->data; + + if (META_WINDOW_IN_TAB_CHAIN (window) && + (workspace == NULL || + meta_window_visible_on_workspace (window, workspace))) + return window; + + tmp = tmp->next; + } + + tmp = display->mru_list; + while (tmp != start) + { + MetaWindow *window = tmp->data; + + if (META_WINDOW_IN_TAB_CHAIN (window) && + (workspace == NULL || + meta_window_visible_on_workspace (window, workspace))) + return window; + + tmp = tmp->next; + } + + return NULL; +} + +static MetaWindow* +find_tab_backward (MetaDisplay *display, + MetaWorkspace *workspace, + GList *start) +{ + GList *tmp; + + g_return_val_if_fail (start != NULL, NULL); + + tmp = start->prev; + while (tmp != NULL) + { + MetaWindow *window = tmp->data; + + if (META_WINDOW_IN_TAB_CHAIN (window) && + (workspace == NULL || + meta_window_visible_on_workspace (window, workspace))) + return window; + + tmp = tmp->prev; + } + + tmp = g_list_last (display->mru_list); + while (tmp != start) + { + MetaWindow *window = tmp->data; + + if (META_WINDOW_IN_TAB_CHAIN (window) && + (workspace == NULL || + meta_window_visible_on_workspace (window, workspace))) + return window; + + tmp = tmp->prev; + } + + return NULL; +} + +GSList* +meta_display_get_tab_list (MetaDisplay *display, + MetaScreen *screen, + MetaWorkspace *workspace) +{ + GSList *tab_list; + + /* workspace can be NULL for all workspaces */ + +#ifdef JOEL_RECOMMENDATION + /* mapping order */ + tab_list = meta_stack_get_tab_list (screen->stack, workspace); +#else + /* Windows sellout mode - MRU order */ + { + GList *tmp; + + tab_list = NULL; + tmp = screen->display->mru_list; + while (tmp != NULL) + { + MetaWindow *window = tmp->data; + + if (window->screen == screen && + META_WINDOW_IN_TAB_CHAIN (window) && + (workspace == NULL || + meta_window_visible_on_workspace (window, workspace))) + tab_list = g_slist_prepend (tab_list, window); + + tmp = tmp->next; + } + tab_list = g_slist_reverse (tab_list); + } +#endif + + return tab_list; +} + +MetaWindow* +meta_display_get_tab_next (MetaDisplay *display, + MetaWorkspace *workspace, + MetaWindow *window, + gboolean backward) +{ +#ifdef JOEL_RECOMMENDATION + return meta_stack_get_tab_next (window->screen->stack, + workspace, + window, + backward); +#else + if (display->mru_list == NULL) + return NULL; + + if (window != NULL) + { + g_assert (window->display == display); + + if (backward) + return find_tab_backward (display, workspace, + g_list_find (display->mru_list, + window)); + else + return find_tab_forward (display, workspace, + g_list_find (display->mru_list, + window)); + } + + if (backward) + return find_tab_backward (display, workspace, + g_list_last (display->mru_list)); + else + return find_tab_forward (display, workspace, + display->mru_list); +#endif +} diff --git a/src/display.h b/src/display.h index 167bef4e5..391ae25dc 100644 --- a/src/display.h +++ b/src/display.h @@ -133,8 +133,10 @@ struct _MetaDisplay */ MetaWindow *focus_window; - /* Previous focus window */ - MetaWindow *prev_focus_window; + /* Most recently focused list. Always contains all + * live windows. + */ + GList *mru_list; GList *workspaces; @@ -271,5 +273,13 @@ void meta_display_ping_window (MetaDisplay *display, gboolean meta_display_window_has_pending_pings (MetaDisplay *display, MetaWindow *window); +GSList* meta_display_get_tab_list (MetaDisplay *display, + MetaScreen *screen, + MetaWorkspace *workspace); + +MetaWindow* meta_display_get_tab_next (MetaDisplay *display, + MetaWorkspace *workspace, + MetaWindow *window, + gboolean backward); #endif diff --git a/src/keybindings.c b/src/keybindings.c index 423e54039..df9a2129b 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -961,10 +961,10 @@ handle_tab_forward (MetaDisplay *display, if (display->focus_window != NULL) { - window = meta_stack_get_tab_next (display->focus_window->screen->stack, - display->focus_window->screen->active_workspace, - display->focus_window, - FALSE); + window = meta_display_get_tab_next (display, + display->focus_window->screen->active_workspace, + display->focus_window, + FALSE); } if (window == NULL) @@ -979,10 +979,10 @@ handle_tab_forward (MetaDisplay *display, */ if (screen) { - window = meta_stack_get_tab_next (screen->stack, - screen->active_workspace, - NULL, - FALSE); + window = meta_display_get_tab_next (screen->display, + screen->active_workspace, + NULL, + FALSE); } } @@ -1022,10 +1022,10 @@ handle_tab_backward (MetaDisplay *display, if (display->focus_window != NULL) { - window = meta_stack_get_tab_next (display->focus_window->screen->stack, - display->focus_window->screen->active_workspace, - display->focus_window, - TRUE); + window = meta_display_get_tab_next (display, + display->focus_window->screen->active_workspace, + display->focus_window, + TRUE); } if (window == NULL) @@ -1040,10 +1040,10 @@ handle_tab_backward (MetaDisplay *display, */ if (screen) { - window = meta_stack_get_tab_next (screen->stack, - screen->active_workspace, - NULL, - TRUE); + window = meta_display_get_tab_next (screen->display, + screen->active_workspace, + NULL, + TRUE); } } @@ -1085,8 +1085,15 @@ handle_focus_previous (MetaDisplay *display, if (screen == NULL) return; - - window = display->prev_focus_window; + + window = NULL; + + /* get previously-focused window, front of list is currently + * focused window + */ + if (display->mru_list && + display->mru_list->next) + window = display->mru_list->next->data; if (window && !meta_window_visible_on_workspace (window, @@ -1096,10 +1103,10 @@ handle_focus_previous (MetaDisplay *display, if (window == NULL) { /* Pick first window in tab order */ - window = meta_stack_get_tab_next (screen->stack, - screen->active_workspace, - NULL, - TRUE); + window = meta_display_get_tab_next (screen->display, + screen->active_workspace, + NULL, + TRUE); } if (window && diff --git a/src/screen.c b/src/screen.c index 0925b7241..764723e6e 100644 --- a/src/screen.c +++ b/src/screen.c @@ -602,8 +602,10 @@ meta_screen_ensure_tab_popup (MetaScreen *screen) if (screen->tab_popup) return; - tab_list = meta_stack_get_tab_list (screen->stack, - screen->active_workspace); + tab_list = meta_display_get_tab_list (screen->display, + screen, + screen->active_workspace); + len = g_slist_length (tab_list); entries = g_new (MetaTabEntry, len + 1); diff --git a/src/stack.c b/src/stack.c index 37b4489af..cebe648a9 100644 --- a/src/stack.c +++ b/src/stack.c @@ -929,8 +929,6 @@ meta_stack_get_default_focus_window (MetaStack *stack, return topmost_dock; } - -#define IN_TAB_CHAIN(w) ((w)->type != META_WINDOW_DOCK && (w)->type != META_WINDOW_DESKTOP) #define GET_XWINDOW(stack, i) (g_array_index ((stack)->windows, \ Window, (i))) @@ -951,7 +949,7 @@ find_tab_forward (MetaStack *stack, window = meta_display_lookup_x_window (stack->screen->display, GET_XWINDOW (stack, i)); - if (window && IN_TAB_CHAIN (window) && + if (window && META_WINDOW_IN_TAB_CHAIN (window) && (workspace == NULL || meta_window_visible_on_workspace (window, workspace))) return window; @@ -967,7 +965,7 @@ find_tab_forward (MetaStack *stack, window = meta_display_lookup_x_window (stack->screen->display, GET_XWINDOW (stack, i)); - if (window && IN_TAB_CHAIN (window) && + if (window && META_WINDOW_IN_TAB_CHAIN (window) && (workspace == NULL || meta_window_visible_on_workspace (window, workspace))) return window; @@ -996,7 +994,7 @@ find_tab_backward (MetaStack *stack, window = meta_display_lookup_x_window (stack->screen->display, GET_XWINDOW (stack, i)); - if (window && IN_TAB_CHAIN (window) && + if (window && META_WINDOW_IN_TAB_CHAIN (window) && (workspace == NULL || meta_window_visible_on_workspace (window, workspace))) return window; @@ -1012,7 +1010,7 @@ find_tab_backward (MetaStack *stack, window = meta_display_lookup_x_window (stack->screen->display, GET_XWINDOW (stack, i)); - if (window && IN_TAB_CHAIN (window) && + if (window && META_WINDOW_IN_TAB_CHAIN (window) && (workspace == NULL || meta_window_visible_on_workspace (window, workspace))) return window; @@ -1094,7 +1092,7 @@ meta_stack_get_tab_list (MetaStack *stack, window = meta_display_lookup_x_window (stack->screen->display, GET_XWINDOW (stack, i)); - if (window && IN_TAB_CHAIN (window) && + if (window && META_WINDOW_IN_TAB_CHAIN (window) && (workspace == NULL || meta_window_visible_on_workspace (window, workspace))) list = g_slist_prepend (list, window); diff --git a/src/window.c b/src/window.c index 27cca9efb..88d0c9d3c 100644 --- a/src/window.c +++ b/src/window.c @@ -590,6 +590,10 @@ meta_window_new (MetaDisplay *display, Window xwindow, window->size_hints.width, window->size_hints.height); + /* add to MRU list */ + window->display->mru_list = + g_list_append (window->display->mru_list, window); + meta_stack_add (window->screen->stack, window); @@ -761,8 +765,8 @@ meta_window_free (MetaWindow *window) if (window->display->focus_window == window) window->display->focus_window = NULL; - if (window->display->prev_focus_window == window) - window->display->prev_focus_window = NULL; + window->display->mru_list = + g_list_remove (window->display->mru_list, window); meta_window_unqueue_calc_showing (window); meta_window_unqueue_move_resize (window); @@ -3185,20 +3189,15 @@ meta_window_notify_focus (MetaWindow *window, * because we won't get a focus out if it occurs, apparently. */ - /* We don't ever want to set prev_focus_window to NULL, - * though it may be NULL due to e.g. only one window ever - * getting focus, or a window disappearing. - */ - /* We ignore grabs, though this is questionable. * It may be better to increase the intelligence of * the focus window tracking. * - * The problem is that keybindings for windows are done - * with XGrabKey, which means focus_window disappears - * and prev_focus_window gets confused from what the - * user expects once a keybinding is used. - */ + * The problem is that keybindings for windows are done with + * XGrabKey, which means focus_window disappears and the front of + * the MRU list gets confused from what the user expects once a + * keybinding is used. + */ meta_topic (META_DEBUG_FOCUS, "Focus %s event received on %s 0x%lx (%s) " "mode %s detail %s\n", @@ -3225,7 +3224,7 @@ meta_window_notify_focus (MetaWindow *window, event->xfocus.detail > NotifyNonlinearVirtual)) { meta_topic (META_DEBUG_FOCUS, - "Ignoring focus event generated by a grab\n"); + "Ignoring focus event generated by a grab or other weirdness\n"); return TRUE; } @@ -3233,18 +3232,15 @@ meta_window_notify_focus (MetaWindow *window, { if (window != window->display->focus_window) { - if (window == window->display->prev_focus_window && - window->display->focus_window != NULL) - { - meta_topic (META_DEBUG_FOCUS, - "%s is now the previous focus window due to another window focused in\n", - window->display->focus_window->desc); - window->display->prev_focus_window = window->display->focus_window; - } meta_topic (META_DEBUG_FOCUS, "* Focus --> %s\n", window->desc); window->display->focus_window = window; window->has_focus = TRUE; + /* Move to the front of the MRU list */ + window->display->mru_list = + g_list_remove (window->display->mru_list, window); + window->display->mru_list = + g_list_prepend (window->display->mru_list, window); if (window->frame) meta_frame_queue_draw (window->frame); } @@ -3267,8 +3263,6 @@ meta_window_notify_focus (MetaWindow *window, meta_topic (META_DEBUG_FOCUS, "%s is now the previous focus window due to being focused out or unmapped\n", window->desc); - - window->display->prev_focus_window = window; meta_topic (META_DEBUG_FOCUS, "* Focus --> NULL (was %s)\n", window->desc); diff --git a/src/window.h b/src/window.h index c7dde93a7..5b7ef6ea1 100644 --- a/src/window.h +++ b/src/window.h @@ -364,4 +364,7 @@ void meta_window_get_work_area (MetaWindow *window, gboolean meta_window_same_application (MetaWindow *window, MetaWindow *other_window); +#define META_WINDOW_IN_TAB_CHAIN(w) \ + ((w)->type != META_WINDOW_DOCK && (w)->type != META_WINDOW_DESKTOP) + #endif