summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhp <rhp>2001-06-24 03:41:44 +0000
committerrhp <rhp>2001-06-24 03:41:44 +0000
commit1b3a58c951f08548d94420c68882b8dacbefda40 (patch)
tree2f6035f76d95203908b9676a32e85f3d1b0025d0
parentbeaac99991700466a367a70c13fade581c175f7d (diff)
downloadmutter-1b3a58c951f08548d94420c68882b8dacbefda40.tar.gz
...
-rw-r--r--src/display.c3
-rw-r--r--src/display.h3
-rw-r--r--src/keybindings.c95
-rw-r--r--src/stack.c60
-rw-r--r--src/stack.h3
-rw-r--r--src/window.c5
6 files changed, 136 insertions, 33 deletions
diff --git a/src/display.c b/src/display.c
index adff3dafe..d422faf16 100644
--- a/src/display.c
+++ b/src/display.c
@@ -162,6 +162,9 @@ meta_display_open (const char *name)
display->error_traps = NULL;
display->server_grab_count = 0;
display->workspaces = NULL;
+
+ display->focus_window = NULL;
+ display->prev_focus_window = NULL;
/* we have to go ahead and do this so error handlers work */
all_displays = g_slist_prepend (all_displays, display);
diff --git a/src/display.h b/src/display.h
index ec74188ad..27c3b6fe5 100644
--- a/src/display.h
+++ b/src/display.h
@@ -100,6 +100,9 @@ struct _MetaDisplay
*/
MetaWindow *focus_window;
+ /* Previous focus window */
+ MetaWindow *prev_focus_window;
+
GList *workspaces;
/*< private-ish >*/
diff --git a/src/keybindings.c b/src/keybindings.c
index 3524e9726..09c6109b8 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -324,28 +324,34 @@ handle_tab_forward (MetaDisplay *display,
if (display->focus_window != NULL)
{
- window = meta_stack_get_above (display->focus_window->screen->stack,
- display->focus_window);
+ window = meta_stack_get_tab_next (display->focus_window->screen->stack,
+ display->focus_window,
+ FALSE);
}
if (window == NULL)
{
- if (event_window)
- window = meta_stack_get_bottom (event_window->screen->stack);
- else
+ MetaScreen *screen;
+
+ screen = meta_display_screen_for_root (display,
+ event->xkey.root);
+
+ /* We get the screen because event_window may be NULL,
+ * in which case we can't use event_window->screen
+ */
+ if (screen)
{
- MetaScreen *screen;
-
- screen = meta_display_screen_for_root (display,
- event->xkey.window);
-
- if (screen)
- window = meta_stack_get_bottom (screen->stack);
+ window = meta_stack_get_tab_next (screen->stack,
+ event_window,
+ FALSE);
}
}
- if (window && window != display->focus_window)
- meta_window_focus (window, event->xkey.time);
+ if (window)
+ {
+ meta_window_raise (window);
+ meta_window_focus (window, event->xkey.time);
+ }
}
static void
@@ -362,29 +368,34 @@ handle_tab_backward (MetaDisplay *display,
if (display->focus_window != NULL)
{
- window = meta_stack_get_below (display->focus_window->screen->stack,
- display->focus_window);
+ window = meta_stack_get_tab_next (display->focus_window->screen->stack,
+ display->focus_window,
+ TRUE);
}
-
+
if (window == NULL)
{
- if (event_window)
- window = meta_stack_get_top (event_window->screen->stack);
+ MetaScreen *screen;
+
+ screen = meta_display_screen_for_root (display,
+ event->xkey.root);
- if (window == NULL)
+ /* We get the screen because event_window may be NULL,
+ * in which case we can't use event_window->screen
+ */
+ if (screen)
{
- MetaScreen *screen;
-
- screen = meta_display_screen_for_root (display,
- event->xkey.window);
-
- if (screen)
- window = meta_stack_get_top (screen->stack);
+ window = meta_stack_get_tab_next (screen->stack,
+ event_window,
+ TRUE);
}
}
- if (window && window != display->focus_window)
- meta_window_focus (window, event->xkey.time);
+ if (window)
+ {
+ meta_window_raise (window);
+ meta_window_focus (window, event->xkey.time);
+ }
}
static void
@@ -399,8 +410,28 @@ handle_focus_previous (MetaDisplay *display,
window = display->prev_focus_window;
+ if (window == NULL)
+ {
+ /* Pick first window in tab order */
+ MetaScreen *screen;
+
+ screen = meta_display_screen_for_root (display,
+ event->xkey.root);
+
+ /* We get the screen because event_window may be NULL,
+ * in which case we can't use event_window->screen
+ */
+ if (screen)
+ {
+ window = meta_stack_get_tab_next (screen->stack,
+ event_window,
+ TRUE);
+ }
+ }
+
if (window)
- meta_window_focus (window, event->xkey.time);
+ {
+ meta_window_raise (window);
+ meta_window_focus (window, event->xkey.time);
+ }
}
-
-
diff --git a/src/stack.c b/src/stack.c
index be6784db8..632e7fcc5 100644
--- a/src/stack.c
+++ b/src/stack.c
@@ -760,3 +760,63 @@ meta_stack_get_below (MetaStack *stack,
else
return find_prev_below_layer (stack, window->layer);
}
+
+MetaWindow*
+meta_stack_get_tab_next (MetaStack *stack,
+ MetaWindow *window,
+ gboolean backward)
+{
+ int i;
+
+ if (stack->windows->len == 0)
+ return NULL;
+
+ if (window != NULL)
+ {
+ i = 0;
+ while (i < stack->windows->len)
+ {
+ Window w;
+
+ w = g_array_index (stack->windows, Window, i);
+
+ if (w == window->xwindow)
+ {
+ if (backward && i == 0)
+ goto out;
+ else if (!backward && i == (stack->windows->len - 1))
+ goto out;
+ else
+ {
+ if (backward)
+ --i;
+ else
+ ++i;
+
+ return meta_display_lookup_x_window (stack->screen->display,
+ g_array_index (stack->windows,
+ Window,
+ i));
+ }
+ }
+
+ ++i;
+ }
+ }
+
+ out:
+
+ /* window may be NULL, or maybe the origin window was already the last/first
+ * window and we need to wrap around
+ */
+ if (backward)
+ return meta_display_lookup_x_window (stack->screen->display,
+ g_array_index (stack->windows,
+ Window,
+ stack->windows->len - 1));
+ else
+ return meta_display_lookup_x_window (stack->screen->display,
+ g_array_index (stack->windows,
+ Window,
+ 0));
+}
diff --git a/src/stack.h b/src/stack.h
index 8e98032af..39cb973a7 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -92,6 +92,9 @@ MetaWindow* meta_stack_get_above (MetaStack *stack,
MetaWindow* meta_stack_get_below (MetaStack *stack,
MetaWindow *window);
+MetaWindow* meta_stack_get_tab_next (MetaStack *stack,
+ MetaWindow *window,
+ gboolean backward);
#endif
diff --git a/src/window.c b/src/window.c
index 61e2c0d16..b243f0bd3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1618,7 +1618,10 @@ meta_window_notify_focus (MetaWindow *window,
*/
if (event->xfocus.mode == NotifyGrab ||
event->xfocus.mode == NotifyUngrab)
- return TRUE;
+ {
+ meta_verbose ("Ignoring focus event generated by a grab\n");
+ return TRUE;
+ }
if (event->type == FocusIn)
{