diff options
author | Elijah Newren <newren@gmail.com> | 2005-01-24 05:58:30 +0000 |
---|---|---|
committer | Elijah Newren <newren@src.gnome.org> | 2005-01-24 05:58:30 +0000 |
commit | 2d0d5e8cac5e67d0d9176352bffeaee78c8be602 (patch) | |
tree | 1af2a541d73c372adae30d1f48ce2f183cdecf73 | |
parent | 814cc4b6985350b7a83fabc81ff4cefbeebdef50 (diff) | |
download | metacity-2d0d5e8cac5e67d0d9176352bffeaee78c8be602.tar.gz |
Restore original stacking when aborting an alt-esc window switch
2005-01-23 Elijah Newren <newren@gmail.com>
Restore original stacking when aborting an alt-esc window switch
operation. Fixes #123576.
* src/display.c: (GRAB_OP_IS_WINDOW_SWITCH): new macro,
(meta_display_close): clear grab_old_window_stacking if non-NULL,
(event_callback): restore stack positions if alt-esc op cancelled
with button press, (meta_display_begin_grab_op): store the old
stacking positions, (meta_display_end_grab_op): free the old stack
positions
* src/display.h: (struct _MetaDisplay): add a
grab_old_window_stacking list
* src/keybindings.c: (process_tab_grab): restore stack positions
if alt-esc op cancelled with an errant key press
* src/stack.c: (compare_just_window_stack_position): new
GCompareFunc function, (meta_stack_get_positions): get current
stack positions, (compare_pointers): new GCompareFunc function,
(lists_contain_same_windows): simple utility func to see if two
lists contains the same windows, (meta_stack_set_positions): new
function to set the positions of all the windows in the stack
* src/stack.h: (meta_stack_get_postions,
meta_stack_set_positions): new functions
-rw-r--r-- | ChangeLog | 28 | ||||
-rw-r--r-- | src/display.c | 43 | ||||
-rw-r--r-- | src/display.h | 1 | ||||
-rw-r--r-- | src/keybindings.c | 5 | ||||
-rw-r--r-- | src/stack.c | 104 | ||||
-rw-r--r-- | src/stack.h | 4 |
6 files changed, 181 insertions, 4 deletions
@@ -1,5 +1,33 @@ 2005-01-23 Elijah Newren <newren@gmail.com> + Restore original stacking when aborting an alt-esc window switch + operation. Fixes #123576. + + * src/display.c: (GRAB_OP_IS_WINDOW_SWITCH): new macro, + (meta_display_close): clear grab_old_window_stacking if non-NULL, + (event_callback): restore stack positions if alt-esc op cancelled + with button press, (meta_display_begin_grab_op): store the old + stacking positions, (meta_display_end_grab_op): free the old stack + positions + + * src/display.h: (struct _MetaDisplay): add a + grab_old_window_stacking list + + * src/keybindings.c: (process_tab_grab): restore stack positions + if alt-esc op cancelled with an errant key press + + * src/stack.c: (compare_just_window_stack_position): new + GCompareFunc function, (meta_stack_get_positions): get current + stack positions, (compare_pointers): new GCompareFunc function, + (lists_contain_same_windows): simple utility func to see if two + lists contains the same windows, (meta_stack_set_positions): new + function to set the positions of all the windows in the stack + + * src/stack.h: (meta_stack_get_postions, + meta_stack_set_positions): new functions + +2005-01-23 Elijah Newren <newren@gmail.com> + Patch from John Paul Wallington to fix #163420. * src/window.c: (check_maximize_to_work_area): fix vertical diff --git a/src/display.c b/src/display.c index 28b05e4b..26a38f2a 100644 --- a/src/display.c +++ b/src/display.c @@ -63,6 +63,12 @@ #define USE_GDK_DISPLAY +#define GRAB_OP_IS_WINDOW_SWITCH(g) \ + (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \ + g == META_GRAB_OP_KEYBOARD_TABBING_DOCK || \ + g == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL || \ + g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK) + typedef struct { MetaDisplay *display; @@ -790,6 +796,9 @@ meta_display_close (MetaDisplay *display) meta_prefs_remove_listener (prefs_changed_callback, display); meta_display_remove_autoraise_callback (display); + + if (display->grab_old_window_stacking) + g_list_free (display->grab_old_window_stacking); #ifdef USE_GDK_DISPLAY /* Stop caring about events */ @@ -1574,6 +1583,16 @@ event_callback (XEvent *event, (display->grab_window ? display->grab_window->desc : "none")); + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) + { + MetaScreen *screen; + meta_topic (META_DEBUG_WINDOW_OPS, + "Syncing to old stack positions.\n"); + screen = + meta_display_screen_for_root (display, event->xany.window); + meta_stack_set_positions (screen->stack, + display->grab_old_window_stacking); + } meta_display_end_grab_op (display, event->xbutton.time); } @@ -3289,6 +3308,16 @@ meta_display_begin_grab_op (MetaDisplay *display, g_assert (display->grab_window != NULL || display->grab_screen != NULL); g_assert (display->grab_op != META_GRAB_OP_NONE); + /* Save the old stacking */ + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op)) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Saving old stack positions; old pointer was %p.\n", + display->grab_old_window_stacking); + display->grab_old_window_stacking = + meta_stack_get_positions (screen->stack); + } + /* Do this last, after everything is set up. */ switch (op) { @@ -3340,10 +3369,7 @@ meta_display_end_grab_op (MetaDisplay *display, if (display->grab_window != NULL) display->grab_window->shaken_loose = FALSE; - if (display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || - display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_DOCK || - display->grab_op == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL || - display->grab_op == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK || + if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) || display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING) { meta_ui_tab_popup_free (display->grab_screen->tab_popup); @@ -3355,6 +3381,15 @@ meta_display_end_grab_op (MetaDisplay *display, display->ungrab_should_not_cause_focus_window = display->grab_xwindow; } + if (display->grab_old_window_stacking != NULL) + { + meta_topic (META_DEBUG_WINDOW_OPS, + "Clearing out the old stack position, which was %p.\n", + display->grab_old_window_stacking); + g_list_free (display->grab_old_window_stacking); + display->grab_old_window_stacking = NULL; + } + if (display->grab_wireframe_active) { display->grab_wireframe_active = FALSE; diff --git a/src/display.h b/src/display.h index a122c35a..6fd41c58 100644 --- a/src/display.h +++ b/src/display.h @@ -265,6 +265,7 @@ struct _MetaDisplay MetaResizePopup *grab_resize_popup; GTimeVal grab_last_moveresize_time; Time grab_motion_notify_time; + GList* grab_old_window_stacking; /* we use property updates as sentinels for certain window focus events * to avoid some race conditions on EnterNotify events diff --git a/src/keybindings.c b/src/keybindings.c index 27e82ce0..154920eb 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -2475,6 +2475,11 @@ process_tab_grab (MetaDisplay *display, /* end grab */ meta_topic (META_DEBUG_KEYBINDINGS, "Ending tabbing/cycling, uninteresting key pressed\n"); + + meta_topic (META_DEBUG_KEYBINDINGS, + "Syncing to old stack positions.\n"); + meta_stack_set_positions (screen->stack, + screen->display->grab_old_window_stacking); } return key_used; diff --git a/src/stack.c b/src/stack.c index f55c6159..a2ffb1e3 100644 --- a/src/stack.c +++ b/src/stack.c @@ -1466,6 +1466,110 @@ meta_stack_windows_cmp (MetaStack *stack, return 0; /* not reached */ } +static int +compare_just_window_stack_position (void *a, + void *b) +{ + MetaWindow *window_a = a; + MetaWindow *window_b = b; + + if (window_a->stack_position < window_b->stack_position) + return -1; /* move window_a earlier in list */ + else if (window_a->stack_position > window_b->stack_position) + return 1; + else + return 0; /* not reached */ +} + +GList* +meta_stack_get_positions (MetaStack *stack) +{ + GList *tmp; + + /* Make sure to handle any adds or removes */ + meta_stack_ensure_sorted (stack); + + tmp = g_list_copy (stack->sorted); + tmp = g_list_sort (tmp, (GCompareFunc) compare_just_window_stack_position); + + return tmp; +} + +gint +compare_pointers (gconstpointer a, + gconstpointer b) +{ + if (a > b) + return 1; + else if (a < b) + return -1; + else + return 0; +} + +static gboolean +lists_contain_same_windows (GList *a, + GList *b) +{ + GList *copy1, *copy2; + GList *tmp1, *tmp2; + + if (g_list_length (a) != g_list_length (b)) + return FALSE; + + tmp1 = copy1 = g_list_sort (g_list_copy (a), compare_pointers); + tmp2 = copy2 = g_list_sort (g_list_copy (b), compare_pointers); + + while (tmp1 && tmp1->data == tmp2->data) /* tmp2 is non-NULL if tmp1 is */ + { + tmp1 = tmp1->next; + tmp2 = tmp2->next; + } + + g_list_free (copy1); + g_list_free (copy2); + + return (tmp1 == NULL); /* tmp2 is non-NULL if tmp1 is */ +} + +void +meta_stack_set_positions (MetaStack *stack, + GList *windows) +{ + int i; + GList *tmp; + + /* Make sure any adds or removes aren't in limbo -- is this needed? */ + meta_stack_ensure_sorted (stack); + + if (!lists_contain_same_windows (windows, stack->sorted)) + { + meta_warning ("This list of windows has somehow changed; not resetting " + "positions of the windows.\n"); + return; + } + + g_list_free (stack->sorted); + stack->sorted = g_list_copy (windows); + + stack->need_resort = TRUE; + stack->need_constrain = TRUE; + + i = 0; + tmp = windows; + while (tmp != NULL) + { + MetaWindow *w = tmp->data; + w->stack_position = i++; + tmp = tmp->next; + } + + meta_topic (META_DEBUG_STACK, + "Reset the stack positions of (nearly) all windows\n"); + + meta_stack_sync_to_server (stack); +} + void meta_window_set_stack_position_no_sync (MetaWindow *window, int position) diff --git a/src/stack.h b/src/stack.h index 0b8d05e2..5cbcf807 100644 --- a/src/stack.h +++ b/src/stack.h @@ -140,4 +140,8 @@ int meta_stack_windows_cmp (MetaStack *stack, void meta_window_set_stack_position (MetaWindow *window, int position); +GList* meta_stack_get_positions (MetaStack *stack); +void meta_stack_set_positions (MetaStack *stack, + GList *windows); + #endif |