From beaac99991700466a367a70c13fade581c175f7d Mon Sep 17 00:00:00 2001 From: rhp Date: Sun, 24 Jun 2001 03:18:10 +0000 Subject: [PATCH] ... --- src/display.c | 9 +++-- src/display.h | 2 + src/frame.c | 6 +-- src/keybindings.c | 66 ++++++++++++++++++++++++++++--- src/keybindings.h | 2 +- src/stack.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++ src/stack.h | 8 ++++ src/window.c | 41 +++++++++++++++++++- src/window.h | 9 ++++- 9 files changed, 226 insertions(+), 16 deletions(-) diff --git a/src/display.c b/src/display.c index 6ff12f0de..adff3dafe 100644 --- a/src/display.c +++ b/src/display.c @@ -127,7 +127,9 @@ meta_display_open (const char *name) "_WIN_WORKSPACE", "_WIN_LAYER", "_WIN_PROTOCOLS", - "_WIN_SUPPORTING_WM_CHECK" + "_WIN_SUPPORTING_WM_CHECK", + "_NET_WM_ICON_NAME", + "_NET_WM_ICON" }; Atom atoms[G_N_ELEMENTS(atom_names)]; @@ -204,6 +206,8 @@ meta_display_open (const char *name) display->atom_win_layer = atoms[33]; display->atom_win_protocols = atoms[34]; display->atom_win_supporting_wm_check = atoms[35]; + display->atom_net_wm_icon_name = atoms[36]; + display->atom_net_wm_icon = atoms[37]; /* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK, * created in screen_new @@ -551,9 +555,8 @@ event_callback (XEvent *event, switch (event->type) { case KeyPress: - meta_display_process_key_press (display, window, event); - break; case KeyRelease: + meta_display_process_key_event (display, window, event); break; case ButtonPress: break; diff --git a/src/display.h b/src/display.h index e5fa6d5f6..ec74188ad 100644 --- a/src/display.h +++ b/src/display.h @@ -92,6 +92,8 @@ struct _MetaDisplay Atom atom_win_layer; Atom atom_win_protocols; Atom atom_win_supporting_wm_check; + Atom atom_net_wm_icon_name; + Atom atom_net_wm_icon; /* This is the actual window from focus events, * not the one we last set diff --git a/src/frame.c b/src/frame.c index 533a8f082..8088e6769 100644 --- a/src/frame.c +++ b/src/frame.c @@ -21,6 +21,7 @@ #include "frame.h" #include "errors.h" +#include "keybindings.h" #define EVENT_MASK (SubstructureRedirectMask | \ StructureNotifyMask | SubstructureNotifyMask | \ @@ -282,10 +283,9 @@ meta_frame_event (MetaFrame *frame, switch (event->type) { case KeyPress: - meta_display_process_key_press (frame->window->display, - frame->window, event); - break; case KeyRelease: + meta_display_process_key_event (frame->window->display, + frame->window, event); break; case ButtonPress: break; diff --git a/src/keybindings.c b/src/keybindings.c index ffc8007fa..3524e9726 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -52,6 +52,10 @@ static void handle_tab_backward (MetaDisplay *display, MetaWindow *window, XEvent *event, gpointer data); +static void handle_focus_previous (MetaDisplay *display, + MetaWindow *window, + XEvent *event, + gpointer data); typedef struct _MetaKeyBinding MetaKeyBinding; @@ -88,6 +92,7 @@ static MetaKeyBinding window_bindings[] = { { XK_Tab, Mod1Mask, KeyPress, handle_tab_forward, NULL, 0 }, { XK_ISO_Left_Tab, ShiftMask | Mod1Mask, KeyPress, handle_tab_backward, NULL, 0 }, { XK_Tab, ShiftMask | Mod1Mask, KeyPress, handle_tab_backward, NULL, 0 }, + { XK_Escape, Mod1Mask, KeyPress, handle_focus_previous, NULL, 0 }, { None, 0, 0, NULL, NULL, 0 } }; @@ -264,7 +269,7 @@ meta_display_process_key_event (MetaDisplay *display, static void handle_activate_workspace (MetaDisplay *display, - MetaWindow *window, + MetaWindow *event_window, XEvent *event, gpointer data) { @@ -287,7 +292,7 @@ handle_activate_workspace (MetaDisplay *display, static void handle_activate_menu (MetaDisplay *display, - MetaWindow *window, + MetaWindow *event_window, XEvent *event, gpointer data) { @@ -307,10 +312,12 @@ handle_activate_menu (MetaDisplay *display, static void handle_tab_forward (MetaDisplay *display, - MetaWindow *window, + MetaWindow *event_window, XEvent *event, gpointer data) { + MetaWindow *window; + meta_verbose ("Tab forward\n"); window = NULL; @@ -322,7 +329,20 @@ handle_tab_forward (MetaDisplay *display, } if (window == NULL) - window = meta_stack_get_bottom (display->focus_window->screen->stack); + { + if (event_window) + window = meta_stack_get_bottom (event_window->screen->stack); + else + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xkey.window); + + if (screen) + window = meta_stack_get_bottom (screen->stack); + } + } if (window && window != display->focus_window) meta_window_focus (window, event->xkey.time); @@ -330,10 +350,12 @@ handle_tab_forward (MetaDisplay *display, static void handle_tab_backward (MetaDisplay *display, - MetaWindow *window, + MetaWindow *event_window, XEvent *event, gpointer data) { + MetaWindow *window; + meta_verbose ("Tab backward\n"); window = NULL; @@ -345,8 +367,40 @@ handle_tab_backward (MetaDisplay *display, } if (window == NULL) - window = meta_stack_get_top (display->focus_window->screen->stack); + { + if (event_window) + window = meta_stack_get_top (event_window->screen->stack); + + if (window == NULL) + { + MetaScreen *screen; + + screen = meta_display_screen_for_root (display, + event->xkey.window); + + if (screen) + window = meta_stack_get_top (screen->stack); + } + } if (window && window != display->focus_window) meta_window_focus (window, event->xkey.time); } + +static void +handle_focus_previous (MetaDisplay *display, + MetaWindow *event_window, + XEvent *event, + gpointer data) +{ + MetaWindow *window; + + meta_verbose ("Focus previous window\n"); + + window = display->prev_focus_window; + + if (window) + meta_window_focus (window, event->xkey.time); +} + + diff --git a/src/keybindings.h b/src/keybindings.h index 3fa610197..f3054dfb1 100644 --- a/src/keybindings.h +++ b/src/keybindings.h @@ -30,7 +30,7 @@ void meta_screen_grab_keys (MetaScreen *screen); void meta_screen_ungrab_keys (MetaScreen *screen); void meta_window_grab_keys (MetaWindow *window); void meta_window_ungrab_keys (MetaWindow *window); -void meta_display_process_key_press (MetaDisplay *display, +void meta_display_process_key_event (MetaDisplay *display, MetaWindow *window, XEvent *event); diff --git a/src/stack.c b/src/stack.c index 89f881b06..be6784db8 100644 --- a/src/stack.c +++ b/src/stack.c @@ -661,3 +661,102 @@ meta_stack_sync_to_server (MetaStack *stack) /* That was scary... */ } +static MetaWindow* +find_next_above_layer (MetaStack *stack, + int layer) +{ + ++layer; + while (layer < META_LAYER_LAST) + { + GList *link; + + g_assert (layer >= 0 && layer < META_LAYER_LAST); + + /* bottom of this layer is at the end of the list */ + link = g_list_last (stack->layers[layer]); + + if (link) + return link->data; + + ++layer; + } + + return NULL; +} + +static MetaWindow* +find_prev_below_layer (MetaStack *stack, + int layer) +{ + --layer; + while (layer >= 0) + { + GList *link; + + g_assert (layer >= 0 && layer < META_LAYER_LAST); + + /* top of this layer is at the front of the list */ + link = stack->layers[layer]; + + if (link) + return link->data; + + --layer; + } + + return NULL; +} + +MetaWindow* +meta_stack_get_top (MetaStack *stack) +{ + /* FIXME if stack is frozen this is kind of broken. */ + + return find_prev_below_layer (stack, META_LAYER_LAST); +} + +MetaWindow* +meta_stack_get_bottom (MetaStack *stack) +{ + /* FIXME if stack is frozen this is kind of broken. */ + + return find_next_above_layer (stack, -1); +} + +MetaWindow* +meta_stack_get_above (MetaStack *stack, + MetaWindow *window) +{ + GList *link; + + /* FIXME if stack is frozen this is kind of broken. */ + + g_assert (window->layer >= 0 && window->layer < META_LAYER_LAST); + link = g_list_find (stack->layers[window->layer], window); + if (link == NULL) + return NULL; + + if (link->prev) + return link->prev->data; + else + return find_next_above_layer (stack, window->layer); +} + +MetaWindow* +meta_stack_get_below (MetaStack *stack, + MetaWindow *window) +{ + GList *link; + + /* FIXME if stack is frozen this is kind of broken. */ + + g_assert (window->layer >= 0 && window->layer < META_LAYER_LAST); + link = g_list_find (stack->layers[window->layer], window); + if (link == NULL) + return NULL; + + if (link->next) + return link->next->data; + else + return find_prev_below_layer (stack, window->layer); +} diff --git a/src/stack.h b/src/stack.h index 0f4c7b52d..8e98032af 100644 --- a/src/stack.h +++ b/src/stack.h @@ -85,6 +85,14 @@ void meta_stack_lower (MetaStack *stack, void meta_stack_freeze (MetaStack *stack); void meta_stack_thaw (MetaStack *stack); +MetaWindow* meta_stack_get_top (MetaStack *stack); +MetaWindow* meta_stack_get_bottom (MetaStack *stack); +MetaWindow* meta_stack_get_above (MetaStack *stack, + MetaWindow *window); +MetaWindow* meta_stack_get_below (MetaStack *stack, + MetaWindow *window); + + #endif diff --git a/src/window.c b/src/window.c index 082fd03e8..61e2c0d16 100644 --- a/src/window.c +++ b/src/window.c @@ -381,6 +381,9 @@ 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; meta_window_unqueue_calc_showing (window); @@ -1599,10 +1602,38 @@ meta_window_notify_focus (MetaWindow *window, * we focus the frame for shaded windows */ + /* 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. + */ + if (event->xfocus.mode == NotifyGrab || + event->xfocus.mode == NotifyUngrab) + return TRUE; + if (event->type == FocusIn) { if (window != window->display->focus_window) - window->display->focus_window = window; + { + if (window == window->display->prev_focus_window && + window->display->focus_window != NULL) + { + meta_verbose ("%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_verbose ("New focus window %s\n", window->desc); + window->display->focus_window = window; + } window->has_focus = TRUE; if (window->frame) meta_frame_queue_draw (window->frame); @@ -1610,7 +1641,13 @@ meta_window_notify_focus (MetaWindow *window, else if (event->type == FocusOut) { if (window == window->display->focus_window) - window->display->focus_window = NULL; + { + meta_verbose ("%s is now the previous focus window due to being focused out\n", + window->desc); + window->display->prev_focus_window = window; + + window->display->focus_window = NULL; + } window->has_focus = FALSE; if (window->frame) meta_frame_queue_draw (window->frame); diff --git a/src/window.h b/src/window.h index 218fd5cb4..41df9fe29 100644 --- a/src/window.h +++ b/src/window.h @@ -26,6 +26,7 @@ #include "util.h" #include "stack.h" #include +#include typedef enum { @@ -51,6 +52,9 @@ struct _MetaWindow char *desc; /* used in debug spew */ char *title; + char *icon_name; + GdkPixbuf *icon; + MetaWindowType type; Atom type_atom; @@ -61,11 +65,14 @@ struct _MetaWindow char *res_name; char *role; char *sm_client_id; - + Window xtransient_for; Window xgroup_leader; Window xclient_leader; + Pixmap icon_pixmap; + Pixmap icon_mask; + /* Initial workspace property */ int initial_workspace;