Clients Menus and Slits are all 'ObWindow's now.
Stacking is done with ObWindows. Slits add themselves to the stacking order, as do clients of course. Added some macros for adding/removing to the stacking order.
This commit is contained in:
parent
506122a110
commit
58cfbb7f84
17 changed files with 244 additions and 169 deletions
|
@ -26,13 +26,13 @@ openbox3_SOURCES=parse.tab.c parse.lex.c action.c client.c config.c \
|
||||||
extensions.c focus.c frame.c grab.c menu.c menu_render.c \
|
extensions.c focus.c frame.c grab.c menu.c menu_render.c \
|
||||||
openbox.c framerender.c parse.c plugin.c prop.c screen.c \
|
openbox.c framerender.c parse.c plugin.c prop.c screen.c \
|
||||||
stacking.c dispatch.c event.c group.c timer.c xerror.c \
|
stacking.c dispatch.c event.c group.c timer.c xerror.c \
|
||||||
moveresize.c startup.c popup.c slit.c
|
moveresize.c startup.c popup.c slit.c window.c
|
||||||
|
|
||||||
noinst_HEADERS=action.h client.h config.h dispatch.h event.h extensions.h \
|
noinst_HEADERS=action.h client.h config.h dispatch.h event.h extensions.h \
|
||||||
focus.h frame.h framerender.h geom.h gettext.h grab.h group.h \
|
focus.h frame.h framerender.h geom.h gettext.h grab.h group.h \
|
||||||
menu.h openbox.h parse.h parse.tab.h plugin.h prop.h screen.h \
|
menu.h openbox.h parse.h parse.tab.h plugin.h prop.h screen.h \
|
||||||
stacking.h timer.h xerror.h moveresize.h startup.h popup.h \
|
stacking.h timer.h xerror.h moveresize.h startup.h popup.h \
|
||||||
slit.h
|
slit.h window.h
|
||||||
|
|
||||||
# kill the implicit .c.y rule
|
# kill the implicit .c.y rule
|
||||||
%.c: %.y
|
%.c: %.y
|
||||||
|
|
|
@ -222,14 +222,14 @@ void action_focusraise(union ActionData *data)
|
||||||
{
|
{
|
||||||
if (data->client.c) {
|
if (data->client.c) {
|
||||||
client_focus(data->client.c);
|
client_focus(data->client.c);
|
||||||
stacking_raise(data->client.c);
|
stacking_raise(CLIENT_AS_WINDOW(data->client.c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_raise(union ActionData *data)
|
void action_raise(union ActionData *data)
|
||||||
{
|
{
|
||||||
if (data->client.c)
|
if (data->client.c)
|
||||||
stacking_raise(data->client.c);
|
stacking_raise(CLIENT_AS_WINDOW(data->client.c));
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_unshaderaise(union ActionData *data)
|
void action_unshaderaise(union ActionData *data)
|
||||||
|
@ -238,7 +238,7 @@ void action_unshaderaise(union ActionData *data)
|
||||||
if (data->client.c->shaded)
|
if (data->client.c->shaded)
|
||||||
client_shade(data->client.c, FALSE);
|
client_shade(data->client.c, FALSE);
|
||||||
else
|
else
|
||||||
stacking_raise(data->client.c);
|
stacking_raise(CLIENT_AS_WINDOW(data->client.c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ void action_shadelower(union ActionData *data)
|
||||||
{
|
{
|
||||||
if (data->client.c) {
|
if (data->client.c) {
|
||||||
if (data->client.c->shaded)
|
if (data->client.c->shaded)
|
||||||
stacking_lower(data->client.c);
|
stacking_lower(CLIENT_AS_WINDOW(data->client.c));
|
||||||
else
|
else
|
||||||
client_shade(data->client.c, TRUE);
|
client_shade(data->client.c, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,7 @@ void action_shadelower(union ActionData *data)
|
||||||
void action_lower(union ActionData *data)
|
void action_lower(union ActionData *data)
|
||||||
{
|
{
|
||||||
if (data->client.c)
|
if (data->client.c)
|
||||||
stacking_lower(data->client.c);
|
stacking_lower(CLIENT_AS_WINDOW(data->client.c));
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_close(union ActionData *data)
|
void action_close(union ActionData *data)
|
||||||
|
|
|
@ -158,7 +158,7 @@ void client_manage_all()
|
||||||
|
|
||||||
w = startup_stack_order[i-1];
|
w = startup_stack_order[i-1];
|
||||||
c = g_hash_table_lookup(client_map, &w);
|
c = g_hash_table_lookup(client_map, &w);
|
||||||
if (c) stacking_lower(c);
|
if (c) stacking_lower(CLIENT_AS_WINDOW(c));
|
||||||
}
|
}
|
||||||
g_free(startup_stack_order);
|
g_free(startup_stack_order);
|
||||||
startup_stack_order = NULL;
|
startup_stack_order = NULL;
|
||||||
|
@ -222,6 +222,7 @@ void client_manage(Window window)
|
||||||
/* create the Client struct, and populate it from the hints on the
|
/* create the Client struct, and populate it from the hints on the
|
||||||
window */
|
window */
|
||||||
self = g_new(Client, 1);
|
self = g_new(Client, 1);
|
||||||
|
self->obwin.type = Window_Client;
|
||||||
self->window = window;
|
self->window = window;
|
||||||
client_get_all(self);
|
client_get_all(self);
|
||||||
|
|
||||||
|
@ -242,14 +243,14 @@ void client_manage(Window window)
|
||||||
grab_server(FALSE);
|
grab_server(FALSE);
|
||||||
|
|
||||||
client_list = g_list_append(client_list, self);
|
client_list = g_list_append(client_list, self);
|
||||||
stacking_list = g_list_append(stacking_list, self);
|
stacking_add(self);
|
||||||
g_assert(!g_hash_table_lookup(client_map, &self->window));
|
g_assert(!g_hash_table_lookup(client_map, &self->window));
|
||||||
g_hash_table_insert(client_map, &self->window, self);
|
g_hash_table_insert(client_map, &self->window, self);
|
||||||
|
|
||||||
/* update the focus lists */
|
/* update the focus lists */
|
||||||
focus_order_add_new(self);
|
focus_order_add_new(self);
|
||||||
|
|
||||||
stacking_raise(self);
|
stacking_raise(CLIENT_AS_WINDOW(self));
|
||||||
|
|
||||||
screen_update_struts();
|
screen_update_struts();
|
||||||
|
|
||||||
|
@ -336,7 +337,7 @@ void client_unmanage(Client *self)
|
||||||
frame_hide(self->frame);
|
frame_hide(self->frame);
|
||||||
|
|
||||||
client_list = g_list_remove(client_list, self);
|
client_list = g_list_remove(client_list, self);
|
||||||
stacking_list = g_list_remove(stacking_list, self);
|
stacking_remove(self);
|
||||||
g_hash_table_remove(client_map, &self->window);
|
g_hash_table_remove(client_map, &self->window);
|
||||||
|
|
||||||
/* update the focus lists */
|
/* update the focus lists */
|
||||||
|
@ -1455,8 +1456,7 @@ static StackLayer calc_layer(Client *self)
|
||||||
{
|
{
|
||||||
StackLayer l;
|
StackLayer l;
|
||||||
|
|
||||||
if (self->iconic) l = Layer_Icon;
|
if (self->fullscreen) l = Layer_Fullscreen;
|
||||||
else if (self->fullscreen) l = Layer_Fullscreen;
|
|
||||||
else if (self->type == Type_Desktop) l = Layer_Desktop;
|
else if (self->type == Type_Desktop) l = Layer_Desktop;
|
||||||
else if (self->type == Type_Dock) {
|
else if (self->type == Type_Dock) {
|
||||||
if (!self->below) l = Layer_Top;
|
if (!self->below) l = Layer_Top;
|
||||||
|
@ -1484,7 +1484,7 @@ static void calc_recursive(Client *self, Client *orig, StackLayer l,
|
||||||
|
|
||||||
if (!raised && l != old)
|
if (!raised && l != old)
|
||||||
if (orig->frame) /* only restack if the original window is managed */
|
if (orig->frame) /* only restack if the original window is managed */
|
||||||
stacking_raise(self);
|
stacking_raise(CLIENT_AS_WINDOW(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_calc_layer(Client *self)
|
void client_calc_layer(Client *self)
|
||||||
|
@ -2028,7 +2028,7 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
|
||||||
client_showhide(self);
|
client_showhide(self);
|
||||||
/* raise if it was not already on the desktop */
|
/* raise if it was not already on the desktop */
|
||||||
if (old != DESKTOP_ALL)
|
if (old != DESKTOP_ALL)
|
||||||
stacking_raise(self);
|
stacking_raise(CLIENT_AS_WINDOW(self));
|
||||||
screen_update_struts();
|
screen_update_struts();
|
||||||
|
|
||||||
/* add to the new desktop(s) */
|
/* add to the new desktop(s) */
|
||||||
|
@ -2310,7 +2310,7 @@ void client_activate(Client *self)
|
||||||
if (self->shaded)
|
if (self->shaded)
|
||||||
client_shade(self, FALSE);
|
client_shade(self, FALSE);
|
||||||
client_focus(self);
|
client_focus(self);
|
||||||
stacking_raise(self);
|
stacking_raise(CLIENT_AS_WINDOW(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean client_focused(Client *self)
|
gboolean client_focused(Client *self)
|
||||||
|
|
|
@ -110,6 +110,8 @@ typedef enum {
|
||||||
|
|
||||||
|
|
||||||
typedef struct Client {
|
typedef struct Client {
|
||||||
|
ObWindow obwin;
|
||||||
|
|
||||||
Window window;
|
Window window;
|
||||||
|
|
||||||
/*! The window's decorations. NULL while the window is being managed! */
|
/*! The window's decorations. NULL while the window is being managed! */
|
||||||
|
|
|
@ -13,6 +13,8 @@ extern gboolean config_focus_last;
|
||||||
extern gboolean config_focus_last_on_desktop;
|
extern gboolean config_focus_last_on_desktop;
|
||||||
/*! Show a popup dialog while cycling focus */
|
/*! Show a popup dialog while cycling focus */
|
||||||
extern gboolean config_focus_popup;
|
extern gboolean config_focus_popup;
|
||||||
|
/*! The number of slits to create */
|
||||||
|
extern int config_slit_number;
|
||||||
|
|
||||||
/* The name of the theme */
|
/* The name of the theme */
|
||||||
char *config_theme;
|
char *config_theme;
|
||||||
|
|
|
@ -916,6 +916,8 @@ static void event_handle_menu(Menu *menu, XEvent *e)
|
||||||
static void event_handle_slit(Slit *s, XEvent *e)
|
static void event_handle_slit(Slit *s, XEvent *e)
|
||||||
{
|
{
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
|
case ButtonPress:
|
||||||
|
stacking_raise(SLIT_AS_WINDOW(s));
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
slit_hide(s, FALSE);
|
slit_hide(s, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,8 +40,7 @@ void focus_startup()
|
||||||
-100, -100, 1, 1, 0,
|
-100, -100, 1, 1, 0,
|
||||||
CopyFromParent, InputOutput, CopyFromParent,
|
CopyFromParent, InputOutput, CopyFromParent,
|
||||||
CWOverrideRedirect, &attrib);
|
CWOverrideRedirect, &attrib);
|
||||||
XMapWindow(ob_display, focus_backup);
|
XMapRaised(ob_display, focus_backup);
|
||||||
stacking_raise_internal(focus_backup);
|
|
||||||
|
|
||||||
/* start with nothing focused */
|
/* start with nothing focused */
|
||||||
focus_set_client(NULL);
|
focus_set_client(NULL);
|
||||||
|
|
|
@ -154,6 +154,7 @@ Menu *menu_new_full(char *label, char *name, Menu *parent,
|
||||||
Menu *self;
|
Menu *self;
|
||||||
|
|
||||||
self = g_new0(Menu, 1);
|
self = g_new0(Menu, 1);
|
||||||
|
self->obwin.type = Window_Menu;
|
||||||
self->label = g_strdup(label);
|
self->label = g_strdup(label);
|
||||||
self->name = g_strdup(name);
|
self->name = g_strdup(name);
|
||||||
self->parent = parent;
|
self->parent = parent;
|
||||||
|
@ -350,7 +351,9 @@ void menu_control_show(Menu *self, int x, int y, Client *client) {
|
||||||
MIN(y, screen_physical_size.height - self->size.height));
|
MIN(y, screen_physical_size.height - self->size.height));
|
||||||
|
|
||||||
if (!self->shown) {
|
if (!self->shown) {
|
||||||
stacking_raise_internal(self->frame);
|
/* XXX gotta add to the stacking list first!
|
||||||
|
stacking_raise(MENU_AS_WINDOW(self));
|
||||||
|
*/
|
||||||
XMapWindow(ob_display, self->frame);
|
XMapWindow(ob_display, self->frame);
|
||||||
self->shown = TRUE;
|
self->shown = TRUE;
|
||||||
} else if (self->shown && self->open_submenu) {
|
} else if (self->shown && self->open_submenu) {
|
||||||
|
|
|
@ -18,6 +18,8 @@ typedef void(*menu_controller_mouseover)(struct MenuEntry *self,
|
||||||
gboolean enter);
|
gboolean enter);
|
||||||
|
|
||||||
typedef struct Menu {
|
typedef struct Menu {
|
||||||
|
ObWindow obwin;
|
||||||
|
|
||||||
char *label;
|
char *label;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
menu_startup();
|
menu_startup();
|
||||||
frame_startup();
|
frame_startup();
|
||||||
stacking_startup();
|
|
||||||
moveresize_startup();
|
moveresize_startup();
|
||||||
focus_startup();
|
focus_startup();
|
||||||
screen_startup();
|
screen_startup();
|
||||||
|
@ -215,7 +214,6 @@ int main(int argc, char **argv)
|
||||||
screen_shutdown();
|
screen_shutdown();
|
||||||
focus_shutdown();
|
focus_shutdown();
|
||||||
moveresize_shutdown();
|
moveresize_shutdown();
|
||||||
stacking_shutdown();
|
|
||||||
frame_shutdown();
|
frame_shutdown();
|
||||||
menu_shutdown();
|
menu_shutdown();
|
||||||
grab_shutdown();
|
grab_shutdown();
|
||||||
|
|
|
@ -1,38 +1,13 @@
|
||||||
#include "slit.h"
|
#include "slit.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "grab.h"
|
#include "grab.h"
|
||||||
#include "timer.h"
|
|
||||||
#include "openbox.h"
|
#include "openbox.h"
|
||||||
#include "render/theme.h"
|
#include "render/theme.h"
|
||||||
#include "render/render.h"
|
|
||||||
|
|
||||||
#define SLIT_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
|
#define SLIT_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
|
||||||
EnterWindowMask | LeaveWindowMask)
|
EnterWindowMask | LeaveWindowMask)
|
||||||
#define SLITAPP_EVENT_MASK (StructureNotifyMask)
|
#define SLITAPP_EVENT_MASK (StructureNotifyMask)
|
||||||
|
|
||||||
struct Slit {
|
|
||||||
Window frame;
|
|
||||||
|
|
||||||
/* user-requested position stuff */
|
|
||||||
SlitPosition pos;
|
|
||||||
int gravity;
|
|
||||||
int user_x, user_y;
|
|
||||||
|
|
||||||
/* actual position (when not auto-hidden) */
|
|
||||||
int x, y;
|
|
||||||
int w, h;
|
|
||||||
|
|
||||||
gboolean horz;
|
|
||||||
gboolean hide;
|
|
||||||
gboolean hidden;
|
|
||||||
|
|
||||||
Appearance *a_frame;
|
|
||||||
|
|
||||||
Timer *hide_timer;
|
|
||||||
|
|
||||||
GList *slit_apps;
|
|
||||||
};
|
|
||||||
|
|
||||||
GHashTable *slit_map = NULL;
|
GHashTable *slit_map = NULL;
|
||||||
GHashTable *slit_app_map = NULL;
|
GHashTable *slit_app_map = NULL;
|
||||||
|
|
||||||
|
@ -53,12 +28,14 @@ void slit_startup()
|
||||||
|
|
||||||
nslits = 1;
|
nslits = 1;
|
||||||
slit = g_new0(struct Slit, nslits);
|
slit = g_new0(struct Slit, nslits);
|
||||||
|
slit->obwin.type = Window_Slit;
|
||||||
|
|
||||||
for (i = 0; i < nslits; ++i) {
|
for (i = 0; i < nslits; ++i) {
|
||||||
slit[i].horz = FALSE;
|
slit[i].horz = FALSE;
|
||||||
slit[i].hide = FALSE;
|
slit[i].hide = FALSE;
|
||||||
slit[i].hidden = TRUE;
|
slit[i].hidden = TRUE;
|
||||||
slit[i].pos = SlitPos_TopRight;
|
slit[i].pos = SlitPos_TopRight;
|
||||||
|
slit[i].layer = Layer_Top;
|
||||||
|
|
||||||
attrib.event_mask = SLIT_EVENT_MASK;
|
attrib.event_mask = SLIT_EVENT_MASK;
|
||||||
attrib.override_redirect = True;
|
attrib.override_redirect = True;
|
||||||
|
@ -71,6 +48,8 @@ void slit_startup()
|
||||||
XSetWindowBorderWidth(ob_display, slit[i].frame, theme_bwidth);
|
XSetWindowBorderWidth(ob_display, slit[i].frame, theme_bwidth);
|
||||||
|
|
||||||
g_hash_table_insert(slit_map, &slit[i].frame, &slit[i]);
|
g_hash_table_insert(slit_map, &slit[i].frame, &slit[i]);
|
||||||
|
stacking_add(&slit[i]);
|
||||||
|
stacking_raise(SLIT_AS_WINDOW(&slit[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +61,7 @@ void slit_shutdown()
|
||||||
XDestroyWindow(ob_display, slit[i].frame);
|
XDestroyWindow(ob_display, slit[i].frame);
|
||||||
appearance_free(slit[i].a_frame);
|
appearance_free(slit[i].a_frame);
|
||||||
g_hash_table_remove(slit_map, &slit[i].frame);
|
g_hash_table_remove(slit_map, &slit[i].frame);
|
||||||
|
stacking_remove(&slit[i]);
|
||||||
}
|
}
|
||||||
g_hash_table_destroy(slit_app_map);
|
g_hash_table_destroy(slit_app_map);
|
||||||
g_hash_table_destroy(slit_map);
|
g_hash_table_destroy(slit_map);
|
||||||
|
|
|
@ -1,24 +1,15 @@
|
||||||
#ifndef __slit_h
|
#ifndef __slit_h
|
||||||
#define __slit_h
|
#define __slit_h
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
#include "render/render.h"
|
||||||
|
#include "window.h"
|
||||||
|
#include "stacking.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
typedef struct Slit Slit;
|
|
||||||
|
|
||||||
typedef struct SlitApp {
|
|
||||||
int ignore_unmaps;
|
|
||||||
|
|
||||||
Slit *slit;
|
|
||||||
Window icon_win;
|
|
||||||
Window win;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int w;
|
|
||||||
int h;
|
|
||||||
} SlitApp;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SlitPos_Floating,
|
SlitPos_Floating,
|
||||||
SlitPos_TopLeft,
|
SlitPos_TopLeft,
|
||||||
|
@ -31,6 +22,44 @@ typedef enum {
|
||||||
SlitPos_Left
|
SlitPos_Left
|
||||||
} SlitPosition;
|
} SlitPosition;
|
||||||
|
|
||||||
|
typedef struct Slit {
|
||||||
|
ObWindow obwin;
|
||||||
|
|
||||||
|
Window frame;
|
||||||
|
StackLayer layer;
|
||||||
|
|
||||||
|
/* user-requested position stuff */
|
||||||
|
SlitPosition pos;
|
||||||
|
int gravity;
|
||||||
|
int user_x, user_y;
|
||||||
|
|
||||||
|
/* actual position (when not auto-hidden) */
|
||||||
|
int x, y;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
gboolean horz;
|
||||||
|
gboolean hide;
|
||||||
|
gboolean hidden;
|
||||||
|
|
||||||
|
Appearance *a_frame;
|
||||||
|
|
||||||
|
Timer *hide_timer;
|
||||||
|
|
||||||
|
GList *slit_apps;
|
||||||
|
} Slit;
|
||||||
|
|
||||||
|
typedef struct SlitApp {
|
||||||
|
int ignore_unmaps;
|
||||||
|
|
||||||
|
Slit *slit;
|
||||||
|
Window icon_win;
|
||||||
|
Window win;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
} SlitApp;
|
||||||
|
|
||||||
extern GHashTable *slit_map;
|
extern GHashTable *slit_map;
|
||||||
extern GHashTable *slit_app_map;
|
extern GHashTable *slit_app_map;
|
||||||
|
|
||||||
|
|
|
@ -4,28 +4,11 @@
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
#include "window.h"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
GList *stacking_list = NULL;
|
GList *stacking_list = NULL;
|
||||||
|
|
||||||
static Window top_window = None;
|
|
||||||
|
|
||||||
void stacking_startup()
|
|
||||||
{
|
|
||||||
XSetWindowAttributes attrib;
|
|
||||||
attrib.override_redirect = TRUE;
|
|
||||||
top_window = XCreateWindow(ob_display, ob_root,
|
|
||||||
-100, -100, 1, 1, 0,
|
|
||||||
CopyFromParent, InputOutput, CopyFromParent,
|
|
||||||
CWOverrideRedirect, &attrib);
|
|
||||||
XMapWindow(ob_display, top_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stacking_shutdown()
|
|
||||||
{
|
|
||||||
XDestroyWindow(ob_display, top_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stacking_set_list()
|
void stacking_set_list()
|
||||||
{
|
{
|
||||||
Window *windows, *win_it;
|
Window *windows, *win_it;
|
||||||
|
@ -44,7 +27,8 @@ void stacking_set_list()
|
||||||
win_it = windows;
|
win_it = windows;
|
||||||
for (it = g_list_last(stacking_list); it != NULL;
|
for (it = g_list_last(stacking_list); it != NULL;
|
||||||
it = it->prev, ++win_it)
|
it = it->prev, ++win_it)
|
||||||
*win_it = ((Client*)it->data)->window;
|
if (WINDOW_IS_CLIENT(it->data))
|
||||||
|
*win_it = window_top(it->data);
|
||||||
} else
|
} else
|
||||||
windows = NULL;
|
windows = NULL;
|
||||||
|
|
||||||
|
@ -67,7 +51,7 @@ static GList *find_lowest_transient(Client *c)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raise_recursive(Client *client)
|
static void raise_recursive(ObWindow *window)
|
||||||
{
|
{
|
||||||
Window wins[2]; /* only ever restack 2 windows. */
|
Window wins[2]; /* only ever restack 2 windows. */
|
||||||
GList *it, *low;
|
GList *it, *low;
|
||||||
|
@ -75,21 +59,27 @@ static void raise_recursive(Client *client)
|
||||||
|
|
||||||
g_assert(stacking_list != NULL); /* this would be bad */
|
g_assert(stacking_list != NULL); /* this would be bad */
|
||||||
|
|
||||||
/* remove the client before looking so we can't run into ourselves and our
|
/* remove the window before looking so we can't run into ourselves and our
|
||||||
transients can't either. */
|
transients can't either. */
|
||||||
stacking_list = g_list_remove(stacking_list, client);
|
stacking_list = g_list_remove(stacking_list, window);
|
||||||
|
|
||||||
/* raise transients first */
|
/* raise transients first */
|
||||||
|
if (WINDOW_IS_CLIENT(window)) {
|
||||||
|
Client *client = WINDOW_AS_CLIENT(window);
|
||||||
for (sit = client->transients; sit; sit = sit->next)
|
for (sit = client->transients; sit; sit = sit->next)
|
||||||
raise_recursive(sit->data);
|
raise_recursive(sit->data);
|
||||||
|
}
|
||||||
|
|
||||||
/* find 'it' where it is the positiion in the stacking order where
|
/* find 'it' where it is the positiion in the stacking order where
|
||||||
'client' will be inserted *before* */
|
'window' will be inserted *before* */
|
||||||
|
|
||||||
low = find_lowest_transient(client);
|
if (WINDOW_IS_CLIENT(window))
|
||||||
|
low = find_lowest_transient(WINDOW_AS_CLIENT(window));
|
||||||
|
else
|
||||||
|
low = NULL;
|
||||||
/* the stacking list is from highest to lowest */
|
/* the stacking list is from highest to lowest */
|
||||||
for (it = g_list_last(stacking_list); it; it = it->prev) {
|
for (it = g_list_last(stacking_list); it; it = it->prev) {
|
||||||
if (it == low || client->layer < ((Client*)it->data)->layer) {
|
if (it == low || window_layer(window) < window_layer(it->data)) {
|
||||||
it = it->next;
|
it = it->next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -104,20 +94,22 @@ static void raise_recursive(Client *client)
|
||||||
if (it == stacking_list)
|
if (it == stacking_list)
|
||||||
wins[0] = focus_backup;
|
wins[0] = focus_backup;
|
||||||
else if (it != NULL)
|
else if (it != NULL)
|
||||||
wins[0] = ((Client*)it->prev->data)->frame->window;
|
wins[0] = window_top(it->prev->data);
|
||||||
else
|
else
|
||||||
wins[0] = ((Client*)g_list_last(stacking_list)->data)->frame->window;
|
wins[0] = window_top(g_list_last(stacking_list)->data);
|
||||||
wins[1] = client->frame->window;
|
wins[1] = window_top(window);
|
||||||
|
|
||||||
stacking_list = g_list_insert_before(stacking_list, it, client);
|
stacking_list = g_list_insert_before(stacking_list, it, window);
|
||||||
|
|
||||||
XRestackWindows(ob_display, wins, 2);
|
XRestackWindows(ob_display, wins, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stacking_raise(Client *client)
|
void stacking_raise(ObWindow *window)
|
||||||
{
|
{
|
||||||
g_assert(stacking_list != NULL); /* this would be bad */
|
g_assert(stacking_list != NULL); /* this would be bad */
|
||||||
|
|
||||||
|
if (WINDOW_IS_CLIENT(window)) {
|
||||||
|
Client *client = WINDOW_AS_CLIENT(window);
|
||||||
/* move up the transient chain as far as possible first */
|
/* move up the transient chain as far as possible first */
|
||||||
while (client->transient_for) {
|
while (client->transient_for) {
|
||||||
if (client->transient_for != TRAN_GROUP) {
|
if (client->transient_for != TRAN_GROUP) {
|
||||||
|
@ -139,42 +131,50 @@ void stacking_raise(Client *client)
|
||||||
if (it == NULL) break;
|
if (it == NULL) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
window = CLIENT_AS_WINDOW(client);
|
||||||
|
}
|
||||||
|
|
||||||
raise_recursive(client);
|
raise_recursive(window);
|
||||||
|
|
||||||
stacking_set_list();
|
stacking_set_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lower_recursive(Client *client, Client *above)
|
static void lower_recursive(ObWindow *window, ObWindow *above)
|
||||||
{
|
{
|
||||||
Window wins[2]; /* only ever restack 2 windows. */
|
Window wins[2]; /* only ever restack 2 windows. */
|
||||||
GList *it;
|
GList *it;
|
||||||
GSList *sit;
|
GSList *sit;
|
||||||
|
|
||||||
/* find 'it' where 'it' is the position in the stacking_list where the
|
/* find 'it' where 'it' is the position in the stacking_list where the
|
||||||
'client' will be placed *after* */
|
'window' will be placed *after* */
|
||||||
|
|
||||||
for (it = g_list_last(stacking_list); it != stacking_list; it = it->prev)
|
for (it = g_list_last(stacking_list); it != stacking_list; it = it->prev)
|
||||||
if (client->layer <= ((Client*)it->data)->layer && it->data != above)
|
if (window_layer(window) <= window_layer(it->data) &&
|
||||||
|
it->data != above)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (it->data != client) { /* not already the bottom */
|
if (it->data != window) { /* not already the bottom */
|
||||||
wins[0] = ((Client*)it->data)->frame->window;
|
wins[0] = window_top(it->data);
|
||||||
wins[1] = client->frame->window;
|
wins[1] = window_top(window);
|
||||||
|
|
||||||
stacking_list = g_list_remove(stacking_list, client);
|
stacking_list = g_list_remove(stacking_list, window);
|
||||||
stacking_list = g_list_insert_before(stacking_list, it->next, client);
|
stacking_list = g_list_insert_before(stacking_list, it->next, window);
|
||||||
XRestackWindows(ob_display, wins, 2);
|
XRestackWindows(ob_display, wins, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WINDOW_IS_CLIENT(window)) {
|
||||||
|
Client *client = WINDOW_AS_CLIENT(window);
|
||||||
for (sit = client->transients; sit; sit = sit->next)
|
for (sit = client->transients; sit; sit = sit->next)
|
||||||
lower_recursive(sit->data, client);
|
lower_recursive(CLIENT_AS_WINDOW(sit->data), window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stacking_lower(Client *client)
|
void stacking_lower(ObWindow *window)
|
||||||
{
|
{
|
||||||
g_assert(stacking_list != NULL); /* this would be bad */
|
g_assert(stacking_list != NULL); /* this would be bad */
|
||||||
|
|
||||||
|
if (WINDOW_IS_CLIENT(window)) {
|
||||||
|
Client *client = WINDOW_AS_CLIENT(window);
|
||||||
/* move up the transient chain as far as possible first */
|
/* move up the transient chain as far as possible first */
|
||||||
while (client->transient_for) {
|
while (client->transient_for) {
|
||||||
if (client->transient_for != TRAN_GROUP) {
|
if (client->transient_for != TRAN_GROUP) {
|
||||||
|
@ -196,18 +196,10 @@ void stacking_lower(Client *client)
|
||||||
if (it == NULL) break;
|
if (it == NULL) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
window = CLIENT_AS_WINDOW(client);
|
||||||
|
}
|
||||||
|
|
||||||
lower_recursive(client, NULL);
|
lower_recursive(window, NULL);
|
||||||
|
|
||||||
stacking_set_list();
|
stacking_set_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
void stacking_raise_internal(Window win)
|
|
||||||
{
|
|
||||||
Window wins[2]; /* only ever restack 2 windows. */
|
|
||||||
|
|
||||||
wins[0] = top_window;
|
|
||||||
wins[1] = win;
|
|
||||||
|
|
||||||
XRestackWindows(ob_display, wins, 2);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,46 +1,42 @@
|
||||||
#ifndef __stacking_h
|
#ifndef __stacking_h
|
||||||
#define __stacking_h
|
#define __stacking_h
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
struct Client;
|
|
||||||
|
|
||||||
/*! The possible stacking layers a client window can be a part of */
|
/*! The possible stacking layers a client window can be a part of */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Layer_Icon, /*!< 0 - iconified windows, in any order at all */
|
Layer_Desktop, /*!< 0 - desktop windows */
|
||||||
Layer_Desktop, /*!< 1 - desktop windows */
|
Layer_Below, /*!< 1 - normal windows w/ below */
|
||||||
Layer_Below, /*!< 2 - normal windows w/ below */
|
Layer_Normal, /*!< 2 - normal windows */
|
||||||
Layer_Normal, /*!< 3 - normal windows */
|
Layer_Above, /*!< 3 - normal windows w/ above */
|
||||||
Layer_Above, /*!< 4 - normal windows w/ above */
|
Layer_Top, /*!< 4 - always-on-top-windows (docks?) */
|
||||||
Layer_Top, /*!< 5 - always-on-top-windows (docks?) */
|
Layer_Fullscreen, /*!< 5 - fullscreeen windows */
|
||||||
Layer_Fullscreen, /*!< 6 - fullscreeen windows */
|
Layer_Internal /*!< 6 - openbox windows/menus */
|
||||||
Layer_Internal /*!< 7 - openbox windows/menus */
|
|
||||||
} StackLayer;
|
} StackLayer;
|
||||||
|
|
||||||
/* list of Client*s in stacking order from highest to lowest */
|
/* list of ObWindow*s in stacking order from highest to lowest */
|
||||||
extern GList *stacking_list;
|
extern GList *stacking_list;
|
||||||
|
|
||||||
void stacking_startup();
|
/*! Sets the window stacking list on the root window from the
|
||||||
void stacking_shutdown();
|
stacking_list */
|
||||||
|
|
||||||
/*! Sets the client stacking list on the root window from the
|
|
||||||
stacking_clientlist */
|
|
||||||
void stacking_set_list();
|
void stacking_set_list();
|
||||||
|
|
||||||
/*! Raises a client window above all others in its stacking layer
|
#define stacking_add(win) stacking_list = g_list_append(stacking_list, win);
|
||||||
|
#define stacking_remove(win) stacking_list = g_list_remove(stacking_list, win);
|
||||||
|
|
||||||
|
/*! Raises a window above all others in its stacking layer
|
||||||
raiseWindow has a couple of constraints that lowerWindow does not.<br>
|
raiseWindow has a couple of constraints that lowerWindow does not.<br>
|
||||||
1) raiseWindow can be called after changing a Client's stack layer, and
|
1) raiseWindow can be called after changing a Window's stack layer, and
|
||||||
the list will be reorganized properly.<br>
|
the list will be reorganized properly.<br>
|
||||||
2) raiseWindow guarantees that XRestackWindows() will <i>always</i> be
|
2) raiseWindow guarantees that XRestackWindows() will <i>always</i> be
|
||||||
called for the specified client.
|
called for the specified window.
|
||||||
*/
|
*/
|
||||||
void stacking_raise(struct Client *client);
|
void stacking_raise(ObWindow *window);
|
||||||
|
|
||||||
/*! Lowers a client window below all others in its stacking layer */
|
/*! Lowers a client window below all others in its stacking layer */
|
||||||
void stacking_lower(struct Client *client);
|
void stacking_lower(ObWindow *window);
|
||||||
|
|
||||||
/*! Raises an internal window (e.g. menus) */
|
|
||||||
void stacking_raise_internal(Window win);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
33
openbox/window.c
Normal file
33
openbox/window.c
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#include "window.h"
|
||||||
|
#include "menu.h"
|
||||||
|
#include "slit.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "frame.h"
|
||||||
|
|
||||||
|
Window window_top(ObWindow *self)
|
||||||
|
{
|
||||||
|
switch (self->type) {
|
||||||
|
case Window_Menu:
|
||||||
|
return ((Menu*)self)->frame;
|
||||||
|
case Window_Slit:
|
||||||
|
return ((Slit*)self)->frame;
|
||||||
|
case Window_Client:
|
||||||
|
return ((Client*)self)->frame->window;
|
||||||
|
}
|
||||||
|
g_assert_not_reached();
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window window_layer(ObWindow *self)
|
||||||
|
{
|
||||||
|
switch (self->type) {
|
||||||
|
case Window_Menu:
|
||||||
|
return Layer_Internal;
|
||||||
|
case Window_Slit:
|
||||||
|
return ((Slit*)self)->layer;
|
||||||
|
case Window_Client:
|
||||||
|
return ((Client*)self)->layer;
|
||||||
|
}
|
||||||
|
g_assert_not_reached();
|
||||||
|
return None;
|
||||||
|
}
|
35
openbox/window.h
Normal file
35
openbox/window.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef __window_h
|
||||||
|
#define __window_h
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Window_Menu,
|
||||||
|
Window_Slit,
|
||||||
|
Window_Client
|
||||||
|
} Window_InternalType;
|
||||||
|
|
||||||
|
typedef struct ObWindow {
|
||||||
|
Window_InternalType type;
|
||||||
|
} ObWindow;
|
||||||
|
|
||||||
|
#define WINDOW_IS_MENU(win) (((ObWindow*)win)->type == Window_Menu)
|
||||||
|
#define WINDOW_IS_SLIT(win) (((ObWindow*)win)->type == Window_Slit)
|
||||||
|
#define WINDOW_IS_CLIENT(win) (((ObWindow*)win)->type == Window_Client)
|
||||||
|
|
||||||
|
struct Menu;
|
||||||
|
struct Slit;
|
||||||
|
struct Client;
|
||||||
|
|
||||||
|
#define WINDOW_AS_MENU(win) ((struct Menu*)win)
|
||||||
|
#define WINDOW_AS_SLIT(win) ((struct Slit*)win)
|
||||||
|
#define WINDOW_AS_CLIENT(win) ((struct Client*)win)
|
||||||
|
|
||||||
|
#define MENU_AS_WINDOW(menu) ((ObWindow*)menu)
|
||||||
|
#define SLIT_AS_WINDOW(slit) ((ObWindow*)slit)
|
||||||
|
#define CLIENT_AS_WINDOW(client) ((ObWindow*)client)
|
||||||
|
|
||||||
|
Window window_top(ObWindow *self);
|
||||||
|
Window window_layer(ObWindow *self);
|
||||||
|
|
||||||
|
#endif
|
|
@ -65,6 +65,8 @@ static void resist_move(Client *c, int *x, int *y)
|
||||||
Client *target;
|
Client *target;
|
||||||
int tl, tt, tr, tb; /* 1 past the target's edges on each side */
|
int tl, tt, tr, tb; /* 1 past the target's edges on each side */
|
||||||
|
|
||||||
|
if (!WINDOW_IS_CLIENT(it->data))
|
||||||
|
continue;
|
||||||
target = it->data;
|
target = it->data;
|
||||||
/* don't snap to self or non-visibles */
|
/* don't snap to self or non-visibles */
|
||||||
if (!target->frame->visible || target == c) continue;
|
if (!target->frame->visible || target == c) continue;
|
||||||
|
|
Loading…
Reference in a new issue