This commit is contained in:
rhp 2001-06-24 03:18:10 +00:00
parent 41a817f11a
commit beaac99991
9 changed files with 226 additions and 16 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -382,6 +382,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);
tmp = window->workspaces;
@ -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);

View File

@ -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;
@ -66,6 +70,9 @@ struct _MetaWindow
Window xgroup_leader;
Window xclient_leader;
Pixmap icon_pixmap;
Pixmap icon_mask;
/* Initial workspace property */
int initial_workspace;