summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhp <rhp>2001-06-24 03:18:10 +0000
committerrhp <rhp>2001-06-24 03:18:10 +0000
commitbeaac99991700466a367a70c13fade581c175f7d (patch)
tree466c3574a30b43f6d4760af100cb479e8c945fa1
parent41a817f11a0b7516a49376ccb0915f457f82882b (diff)
downloadmetacity-beaac99991700466a367a70c13fade581c175f7d.tar.gz
metacity-beaac99991700466a367a70c13fade581c175f7d.tar.bz2
...
-rw-r--r--src/display.c9
-rw-r--r--src/display.h2
-rw-r--r--src/frame.c6
-rw-r--r--src/keybindings.c66
-rw-r--r--src/keybindings.h2
-rw-r--r--src/stack.c99
-rw-r--r--src/stack.h8
-rw-r--r--src/window.c41
-rw-r--r--src/window.h9
9 files changed, 226 insertions, 16 deletions
diff --git a/src/display.c b/src/display.c
index 6ff12f0..adff3da 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 e5fa6d5..ec74188 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 533a8f0..8088e67 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 ffc8007..3524e97 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 3fa6101..f3054df 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 89f881b..be6784d 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 0f4c7b5..8e98032 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 082fd03..61e2c0d 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 218fd5c..41df9fe 100644
--- a/src/window.h
+++ b/src/window.h
@@ -26,6 +26,7 @@
#include "util.h"
#include "stack.h"
#include <X11/Xutil.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
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;