...
This commit is contained in:
parent
41a817f11a
commit
beaac99991
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
99
src/stack.c
99
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
41
src/window.c
41
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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user