mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
...
This commit is contained in:
parent
7f55a13291
commit
2f29ba4f39
@ -57,6 +57,8 @@ metacity_SOURCES= \
|
|||||||
screen.h \
|
screen.h \
|
||||||
session.c \
|
session.c \
|
||||||
session.h \
|
session.h \
|
||||||
|
stack.c \
|
||||||
|
stack.h \
|
||||||
theme.c \
|
theme.c \
|
||||||
theme.h \
|
theme.h \
|
||||||
uislave.c \
|
uislave.c \
|
||||||
|
@ -116,7 +116,9 @@ meta_display_open (const char *name)
|
|||||||
"_NET_WM_WINDOW_TYPE_MENU",
|
"_NET_WM_WINDOW_TYPE_MENU",
|
||||||
"_NET_WM_WINDOW_TYPE_DIALOG",
|
"_NET_WM_WINDOW_TYPE_DIALOG",
|
||||||
"_NET_WM_WINDOW_TYPE_NORMAL",
|
"_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)];
|
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_dialog = atoms[25];
|
||||||
display->atom_net_wm_window_type_normal = atoms[26];
|
display->atom_net_wm_window_type_normal = atoms[26];
|
||||||
display->atom_net_wm_state_modal = atoms[27];
|
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;
|
screens = NULL;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -74,6 +74,8 @@ struct _MetaDisplay
|
|||||||
Atom atom_net_wm_window_type_dialog;
|
Atom atom_net_wm_window_type_dialog;
|
||||||
Atom atom_net_wm_window_type_normal;
|
Atom atom_net_wm_window_type_normal;
|
||||||
Atom atom_net_wm_state_modal;
|
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,
|
/* This is the actual window from focus events,
|
||||||
* not the one we last set
|
* not the one we last set
|
||||||
|
@ -9,7 +9,7 @@ elif test -z "$DEBUG"; then
|
|||||||
DEBUG=gdb
|
DEBUG=gdb
|
||||||
fi
|
fi
|
||||||
|
|
||||||
Xnest :1 -scrns $SCREENS -geometry 640x480 &
|
Xnest :1 -scrns $SCREENS -geometry 640x480 -bw 15 &
|
||||||
DISPLAY=:1 xsetroot -solid royalblue3
|
usleep 50000
|
||||||
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity
|
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity
|
||||||
killall Xnest
|
killall Xnest
|
||||||
|
125
src/stack.c
125
src/stack.c
@ -20,6 +20,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
|
#include "window.h"
|
||||||
|
#include "errors.h"
|
||||||
|
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
struct _MetaStackOp
|
struct _MetaStackOp
|
||||||
{
|
{
|
||||||
@ -63,6 +67,7 @@ void
|
|||||||
meta_stack_free (MetaStack *stack)
|
meta_stack_free (MetaStack *stack)
|
||||||
{
|
{
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
g_array_free (stack->windows, TRUE);
|
g_array_free (stack->windows, TRUE);
|
||||||
|
|
||||||
@ -251,6 +256,56 @@ compute_layer (MetaWindow *window)
|
|||||||
window->layer = META_LAYER_NORMAL;
|
window->layer = META_LAYER_NORMAL;
|
||||||
break;
|
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
|
static void
|
||||||
@ -265,11 +320,17 @@ meta_stack_sync_to_server (MetaStack *stack)
|
|||||||
int n_actually_added;
|
int n_actually_added;
|
||||||
int i, j;
|
int i, j;
|
||||||
int old_size;
|
int old_size;
|
||||||
|
GArray *stacked;
|
||||||
|
|
||||||
/* Bail out if frozen */
|
/* Bail out if frozen */
|
||||||
if (stack->freeze_count > 0)
|
if (stack->freeze_count > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (stack->pending == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
meta_verbose ("Syncing window stack to server\n");
|
||||||
|
|
||||||
/* Here comes the fun - figure out all the stacking.
|
/* Here comes the fun - figure out all the stacking.
|
||||||
* We make no pretense of efficiency.
|
* We make no pretense of efficiency.
|
||||||
* a) replay all the pending operations
|
* a) replay all the pending operations
|
||||||
@ -304,7 +365,7 @@ meta_stack_sync_to_server (MetaStack *stack)
|
|||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_size = stack->window->len;
|
old_size = stack->windows->len;
|
||||||
g_array_set_size (stack->windows,
|
g_array_set_size (stack->windows,
|
||||||
old_size + n_actually_added);
|
old_size + n_actually_added);
|
||||||
|
|
||||||
@ -447,25 +508,81 @@ meta_stack_sync_to_server (MetaStack *stack)
|
|||||||
stack->pending = NULL;
|
stack->pending = NULL;
|
||||||
stack->n_added = 0;
|
stack->n_added = 0;
|
||||||
|
|
||||||
|
|
||||||
/* Sort the layer lists */
|
/* Sort the layer lists */
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < META_LAYER_LAST)
|
while (i < META_LAYER_LAST)
|
||||||
{
|
{
|
||||||
if (needs_sort[i])
|
if (needs_sort[i])
|
||||||
{
|
{
|
||||||
|
stack->layers[i] =
|
||||||
|
g_list_sort (stack->layers[i],
|
||||||
|
(GCompareFunc) window_stack_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create stacked xwindow array */
|
/* 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 */
|
/* 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 */
|
/* 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 void recalc_window_type (MetaWindow *window);
|
||||||
static int set_wm_state (MetaWindow *window,
|
static int set_wm_state (MetaWindow *window,
|
||||||
int state);
|
int state);
|
||||||
|
static int set_net_wm_state (MetaWindow *window);
|
||||||
static void send_configure_notify (MetaWindow *window);
|
static void send_configure_notify (MetaWindow *window);
|
||||||
static gboolean process_configure_request (MetaWindow *window,
|
static gboolean process_configure_request (MetaWindow *window,
|
||||||
int x,
|
int x,
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "stack.h"
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -226,3 +226,6 @@ set_active_space_hint (MetaScreen *screen)
|
|||||||
32, PropModeReplace, (guchar*) data, 1);
|
32, PropModeReplace, (guchar*) data, 1);
|
||||||
return meta_error_trap_pop (screen->display);
|
return meta_error_trap_pop (screen->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user