...
This commit is contained in:
parent
7f55a13291
commit
2f29ba4f39
9 changed files with 230 additions and 8 deletions
|
@ -57,6 +57,8 @@ metacity_SOURCES= \
|
|||
screen.h \
|
||||
session.c \
|
||||
session.h \
|
||||
stack.c \
|
||||
stack.h \
|
||||
theme.c \
|
||||
theme.h \
|
||||
uislave.c \
|
||||
|
|
|
@ -116,7 +116,9 @@ meta_display_open (const char *name)
|
|||
"_NET_WM_WINDOW_TYPE_MENU",
|
||||
"_NET_WM_WINDOW_TYPE_DIALOG",
|
||||
"_NET_WM_WINDOW_TYPE_NORMAL",
|
||||
"_NET_WM_STATE_MODAL"
|
||||
"_NET_WM_STATE_MODAL",
|
||||
"_NET_CLIENT_LIST",
|
||||
"_NET_CLIENT_LIST_STACKING"
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
|
@ -181,6 +183,8 @@ meta_display_open (const char *name)
|
|||
display->atom_net_wm_window_type_dialog = atoms[25];
|
||||
display->atom_net_wm_window_type_normal = atoms[26];
|
||||
display->atom_net_wm_state_modal = atoms[27];
|
||||
display->atom_net_client_list = atoms[28];
|
||||
display->atom_net_client_list_stacking = atoms[29];
|
||||
|
||||
screens = NULL;
|
||||
i = 0;
|
||||
|
|
|
@ -74,6 +74,8 @@ struct _MetaDisplay
|
|||
Atom atom_net_wm_window_type_dialog;
|
||||
Atom atom_net_wm_window_type_normal;
|
||||
Atom atom_net_wm_state_modal;
|
||||
Atom atom_net_client_list;
|
||||
Atom atom_net_client_list_stacking;
|
||||
|
||||
/* This is the actual window from focus events,
|
||||
* not the one we last set
|
||||
|
|
|
@ -9,7 +9,7 @@ elif test -z "$DEBUG"; then
|
|||
DEBUG=gdb
|
||||
fi
|
||||
|
||||
Xnest :1 -scrns $SCREENS -geometry 640x480 &
|
||||
DISPLAY=:1 xsetroot -solid royalblue3
|
||||
Xnest :1 -scrns $SCREENS -geometry 640x480 -bw 15 &
|
||||
usleep 50000
|
||||
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity
|
||||
killall Xnest
|
||||
|
|
127
src/stack.c
127
src/stack.c
|
@ -20,6 +20,10 @@
|
|||
*/
|
||||
|
||||
#include "stack.h"
|
||||
#include "window.h"
|
||||
#include "errors.h"
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
struct _MetaStackOp
|
||||
{
|
||||
|
@ -63,6 +67,7 @@ void
|
|||
meta_stack_free (MetaStack *stack)
|
||||
{
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
g_array_free (stack->windows, TRUE);
|
||||
|
||||
|
@ -251,6 +256,56 @@ compute_layer (MetaWindow *window)
|
|||
window->layer = META_LAYER_NORMAL;
|
||||
break;
|
||||
}
|
||||
|
||||
meta_verbose ("Window %s on layer %d\n",
|
||||
window->desc, window->layer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_transient_for (MetaWindow *transient,
|
||||
MetaWindow *parent)
|
||||
{
|
||||
MetaWindow *w;
|
||||
|
||||
w = transient;
|
||||
while (w != NULL)
|
||||
{
|
||||
if (w->xtransient_for == None)
|
||||
return FALSE;
|
||||
|
||||
w = meta_display_lookup_x_window (w->display, w->xtransient_for);
|
||||
|
||||
if (w == transient)
|
||||
return FALSE; /* Cycle detected */
|
||||
else if (w == parent)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
window_stack_cmp (MetaWindow *a,
|
||||
MetaWindow *b)
|
||||
{
|
||||
/* Less than means higher in stacking, i.e. at the
|
||||
* front of the list.
|
||||
*/
|
||||
|
||||
if (a->xtransient_for != None &&
|
||||
is_transient_for (a, b))
|
||||
{
|
||||
/* a is higher than b due to transient_for */
|
||||
return -1;
|
||||
}
|
||||
else if (b->xtransient_for != None &&
|
||||
is_transient_for (b, a))
|
||||
{
|
||||
/* b is higher than a due to transient_for */
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0; /* leave things as-is */
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -265,11 +320,17 @@ meta_stack_sync_to_server (MetaStack *stack)
|
|||
int n_actually_added;
|
||||
int i, j;
|
||||
int old_size;
|
||||
GArray *stacked;
|
||||
|
||||
/* Bail out if frozen */
|
||||
if (stack->freeze_count > 0)
|
||||
return;
|
||||
|
||||
if (stack->pending == NULL)
|
||||
return;
|
||||
|
||||
meta_verbose ("Syncing window stack to server\n");
|
||||
|
||||
/* Here comes the fun - figure out all the stacking.
|
||||
* We make no pretense of efficiency.
|
||||
* a) replay all the pending operations
|
||||
|
@ -304,7 +365,7 @@ meta_stack_sync_to_server (MetaStack *stack)
|
|||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
old_size = stack->window->len;
|
||||
old_size = stack->windows->len;
|
||||
g_array_set_size (stack->windows,
|
||||
old_size + n_actually_added);
|
||||
|
||||
|
@ -447,25 +508,81 @@ meta_stack_sync_to_server (MetaStack *stack)
|
|||
stack->pending = NULL;
|
||||
stack->n_added = 0;
|
||||
|
||||
|
||||
/* Sort the layer lists */
|
||||
i = 0;
|
||||
while (i < META_LAYER_LAST)
|
||||
{
|
||||
if (needs_sort[i])
|
||||
{
|
||||
|
||||
|
||||
stack->layers[i] =
|
||||
g_list_sort (stack->layers[i],
|
||||
(GCompareFunc) window_stack_cmp);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Create stacked xwindow array */
|
||||
stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||
i = 0;
|
||||
while (i < META_LAYER_LAST)
|
||||
{
|
||||
if (needs_sort[i])
|
||||
{
|
||||
stack->layers[i] =
|
||||
g_list_sort (stack->layers[i],
|
||||
(GCompareFunc) window_stack_cmp);
|
||||
}
|
||||
|
||||
tmp = stack->layers[i];
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
g_array_append_val (stacked, w->xwindow);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
/* All windows should be in some stacking order */
|
||||
if (stacked->len != stack->windows->len)
|
||||
meta_bug ("%d windows stacked, %d windows exist in stack\n",
|
||||
stacked->len, stack->windows->len);
|
||||
|
||||
/* Sync to server */
|
||||
|
||||
meta_error_trap_push (stack->screen->display);
|
||||
XRestackWindows (stack->screen->display->xdisplay,
|
||||
(Window *) stacked->data,
|
||||
stacked->len);
|
||||
meta_error_trap_pop (stack->screen->display);
|
||||
/* on error, a window was destroyed; it should eventually
|
||||
* get removed from the stacking list when we unmanage it
|
||||
* and we'll fix stacking at that time.
|
||||
*/
|
||||
|
||||
/* Sync _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING */
|
||||
|
||||
|
||||
XChangeProperty (stack->screen->display->xdisplay,
|
||||
stack->screen->xroot,
|
||||
stack->screen->display->atom_net_client_list,
|
||||
XA_ATOM,
|
||||
32, PropModeReplace,
|
||||
stack->windows->data,
|
||||
stack->windows->len);
|
||||
XChangeProperty (stack->screen->display->xdisplay,
|
||||
stack->screen->xroot,
|
||||
stack->screen->display->atom_net_client_list_stacking,
|
||||
XA_ATOM,
|
||||
32, PropModeReplace,
|
||||
stacked->data,
|
||||
stacked->len);
|
||||
|
||||
g_array_free (stacked, TRUE);
|
||||
|
||||
/* That was scary... */
|
||||
}
|
||||
|
||||
|
|
92
src/stack.h
Normal file
92
src/stack.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* Metacity Window Stack */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_STACK_H
|
||||
#define META_STACK_H
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
/* Type of last-queued stacking operation, hung off of MetaWindow
|
||||
* but an opaque type used only in stack.c
|
||||
*/
|
||||
typedef struct _MetaStackOp MetaStackOp;
|
||||
|
||||
/* These MUST be in the order of stacking */
|
||||
typedef enum
|
||||
{
|
||||
META_LAYER_DESKTOP = 0,
|
||||
META_LAYER_BOTTOM = 1,
|
||||
META_LAYER_NORMAL = 2,
|
||||
META_LAYER_TOP = 3,
|
||||
META_LAYER_DOCK = 4,
|
||||
META_LAYER_LAST = 5
|
||||
} MetaStackLayer;
|
||||
|
||||
struct _MetaStack
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
/* All windows that we manage, in mapping order,
|
||||
* for _NET_CLIENT_LIST
|
||||
*/
|
||||
GArray *windows;
|
||||
|
||||
/* List of MetaWindow* in each layer */
|
||||
GList *layers[META_LAYER_LAST];
|
||||
|
||||
/* List of MetaStackOp, most recent op
|
||||
* first in list.
|
||||
*/
|
||||
GList *pending;
|
||||
|
||||
int freeze_count;
|
||||
|
||||
int n_added;
|
||||
};
|
||||
|
||||
MetaStack *meta_stack_new (MetaScreen *screen);
|
||||
void meta_stack_free (MetaStack *stack);
|
||||
void meta_stack_add (MetaStack *stack,
|
||||
MetaWindow *window);
|
||||
void meta_stack_remove (MetaStack *stack,
|
||||
MetaWindow *window);
|
||||
/* re-read layer-related hints */
|
||||
void meta_stack_update_layer (MetaStack *stack,
|
||||
MetaWindow *window);
|
||||
/* reconsider transient_for */
|
||||
void meta_stack_update_transient (MetaStack *stack,
|
||||
MetaWindow *window);
|
||||
|
||||
/* raise/lower within a layer */
|
||||
void meta_stack_raise (MetaStack *stack,
|
||||
MetaWindow *window);
|
||||
void meta_stack_lower (MetaStack *stack,
|
||||
MetaWindow *window);
|
||||
|
||||
/* On thaw, process pending and sync to server */
|
||||
void meta_stack_freeze (MetaStack *stack);
|
||||
void meta_stack_thaw (MetaStack *stack);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -53,6 +53,7 @@ static int update_net_wm_type (MetaWindow *window);
|
|||
static void recalc_window_type (MetaWindow *window);
|
||||
static int set_wm_state (MetaWindow *window,
|
||||
int state);
|
||||
static int set_net_wm_state (MetaWindow *window);
|
||||
static void send_configure_notify (MetaWindow *window);
|
||||
static gboolean process_configure_request (MetaWindow *window,
|
||||
int x,
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "screen.h"
|
||||
#include "util.h"
|
||||
#include "stack.h"
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -226,3 +226,6 @@ set_active_space_hint (MetaScreen *screen)
|
|||
32, PropModeReplace, (guchar*) data, 1);
|
||||
return meta_error_trap_pop (screen->display);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue