summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2005-01-24 05:58:30 +0000
committerElijah Newren <newren@src.gnome.org>2005-01-24 05:58:30 +0000
commit2d0d5e8cac5e67d0d9176352bffeaee78c8be602 (patch)
tree1af2a541d73c372adae30d1f48ce2f183cdecf73 /src
parent814cc4b6985350b7a83fabc81ff4cefbeebdef50 (diff)
downloadmetacity-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
Diffstat (limited to 'src')
-rw-r--r--src/display.c43
-rw-r--r--src/display.h1
-rw-r--r--src/keybindings.c5
-rw-r--r--src/stack.c104
-rw-r--r--src/stack.h4
5 files changed, 153 insertions, 4 deletions
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