add internal popups n shit to the stacking list.
some cleanups for the stacking order hint. add non-opaque move/resize. cant toggle it yet.
This commit is contained in:
parent
fed4a9e70b
commit
7c7868f47d
7 changed files with 141 additions and 13 deletions
|
@ -638,13 +638,13 @@ static void event_handle_client(Client *client, XEvent *e)
|
|||
switch (e->xconfigurerequest.detail) {
|
||||
case Below:
|
||||
case BottomIf:
|
||||
stacking_lower(client);
|
||||
stacking_lower(CLIENT_AS_WINDOW(client));
|
||||
break;
|
||||
|
||||
case Above:
|
||||
case TopIf:
|
||||
default:
|
||||
stacking_raise(client);
|
||||
stacking_raise(CLIENT_AS_WINDOW(client));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -689,7 +689,7 @@ static void event_handle_client(Client *client, XEvent *e)
|
|||
if (client->shaded)
|
||||
client_shade(client, FALSE);
|
||||
client_focus(client);
|
||||
stacking_raise(client);
|
||||
stacking_raise(CLIENT_AS_WINDOW(client));
|
||||
break;
|
||||
case ClientMessage:
|
||||
/* validate cuz we query stuff off the client here */
|
||||
|
|
|
@ -201,6 +201,7 @@ Menu *menu_new_full(char *label, char *name, Menu *parent,
|
|||
g_hash_table_insert(menu_hash, g_strdup(name), self);
|
||||
|
||||
stacking_add(self);
|
||||
stacking_raise(MENU_AS_WINDOW(self));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#include "grab.h"
|
||||
#include "framerender.h"
|
||||
#include "screen.h"
|
||||
#include "prop.h"
|
||||
#include "client.h"
|
||||
#include "dispatch.h"
|
||||
#include "openbox.h"
|
||||
#include "popup.h"
|
||||
#include "render/render.h"
|
||||
#include "render/theme.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <glib.h>
|
||||
|
@ -24,12 +27,21 @@ static guint button_return, button_escape, button_left, button_right,
|
|||
button_up, button_down;
|
||||
|
||||
static Popup *popup = NULL;
|
||||
static InternalWindow opaque_window = { { Window_Internal }, None };
|
||||
static GC opaque_gc = None;
|
||||
static gboolean first_draw = FALSE;
|
||||
|
||||
#define POPUP_X (10)
|
||||
#define POPUP_Y (10)
|
||||
|
||||
gboolean config_opaque_move = FALSE;
|
||||
gboolean config_opaque_resize = FALSE;
|
||||
|
||||
void moveresize_startup()
|
||||
{
|
||||
XSetWindowAttributes attrib;
|
||||
XGCValues gcv;
|
||||
|
||||
button_return = XKeysymToKeycode(ob_display, XStringToKeysym("Return"));
|
||||
button_escape = XKeysymToKeycode(ob_display, XStringToKeysym("Escape"));
|
||||
button_left = XKeysymToKeycode(ob_display, XStringToKeysym("Left"));
|
||||
|
@ -40,12 +52,30 @@ void moveresize_startup()
|
|||
popup = popup_new(FALSE);
|
||||
popup_size_to_string(popup, "W: 0000 W: 0000");
|
||||
popup_position(popup, NorthWestGravity, POPUP_X, POPUP_Y);
|
||||
|
||||
attrib.save_under = True;
|
||||
opaque_window.win = XCreateWindow(ob_display, ob_root, 0, 0, 1, 1, 0,
|
||||
render_depth, InputOutput, render_visual,
|
||||
CWSaveUnder, &attrib);
|
||||
stacking_add(&opaque_window);
|
||||
stacking_raise(INTERNAL_AS_WINDOW(&opaque_window));
|
||||
|
||||
/* a GC to invert stuff */
|
||||
gcv.function = GXxor;
|
||||
gcv.line_width = theme_bwidth;
|
||||
gcv.foreground = (WhitePixel(ob_display, ob_screen) ^
|
||||
BlackPixel(ob_display, ob_screen));
|
||||
opaque_gc = XCreateGC(ob_display, opaque_window.win,
|
||||
GCFunction | GCForeground | GCLineWidth, &gcv);
|
||||
}
|
||||
|
||||
void moveresize_shutdown()
|
||||
{
|
||||
popup_free(popup);
|
||||
popup = NULL;
|
||||
stacking_remove(&opaque_window);
|
||||
XFreeGC(ob_display, opaque_gc);
|
||||
XDestroyWindow(ob_display, opaque_window.win);
|
||||
}
|
||||
|
||||
static void popup_coords(char *format, int a, int b)
|
||||
|
@ -117,10 +147,25 @@ void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr)
|
|||
|
||||
grab_pointer(TRUE, cur);
|
||||
grab_keyboard(TRUE);
|
||||
|
||||
XResizeWindow(ob_display, opaque_window.win, screen_physical_size.width,
|
||||
screen_physical_size.height);
|
||||
stacking_raise(INTERNAL_AS_WINDOW(&opaque_window));
|
||||
if (corner == prop_atoms.net_wm_moveresize_move ||
|
||||
corner == prop_atoms.net_wm_moveresize_move_keyboard) {
|
||||
if (!config_opaque_move)
|
||||
XMapWindow(ob_display, opaque_window.win);
|
||||
} else {
|
||||
if (!config_opaque_resize)
|
||||
XMapWindow(ob_display, opaque_window.win);
|
||||
}
|
||||
first_draw = TRUE;
|
||||
}
|
||||
|
||||
void moveresize_end(gboolean cancel)
|
||||
{
|
||||
XUnmapWindow(ob_display, opaque_window.win);
|
||||
|
||||
grab_keyboard(FALSE);
|
||||
grab_pointer(FALSE, None);
|
||||
|
||||
|
@ -145,12 +190,30 @@ void moveresize_end(gboolean cancel)
|
|||
|
||||
static void do_move()
|
||||
{
|
||||
int oldx, oldy, oldw, oldh;
|
||||
|
||||
dispatch_move(moveresize_client, &cur_x, &cur_y);
|
||||
|
||||
oldx = moveresize_client->frame->area.x;
|
||||
oldy = moveresize_client->frame->area.y;
|
||||
oldw = moveresize_client->frame->area.width;
|
||||
oldh = moveresize_client->frame->area.height;
|
||||
/* get where the client should be */
|
||||
frame_frame_gravity(moveresize_client->frame, &cur_x, &cur_y);
|
||||
client_configure(moveresize_client, Corner_TopLeft, cur_x, cur_y,
|
||||
start_cw, start_ch, TRUE, FALSE);
|
||||
/* draw the new one */
|
||||
if (!config_opaque_move)
|
||||
XDrawRectangle(ob_display, opaque_window.win, opaque_gc,
|
||||
moveresize_client->frame->area.x,
|
||||
moveresize_client->frame->area.y,
|
||||
moveresize_client->frame->area.width - 1,
|
||||
moveresize_client->frame->area.height - 1);
|
||||
/* erase the old one */
|
||||
if (!config_opaque_move && !first_draw)
|
||||
XDrawRectangle(ob_display, opaque_window.win, opaque_gc,
|
||||
oldx, oldy, oldw - 1, oldh - 1);
|
||||
first_draw = FALSE;
|
||||
|
||||
/* this would be better with a fixed width font ... XXX can do it better
|
||||
if there are 2 text boxes */
|
||||
|
@ -160,6 +223,8 @@ static void do_move()
|
|||
|
||||
static void do_resize()
|
||||
{
|
||||
int oldx, oldy, oldw, oldh;
|
||||
|
||||
/* dispatch_resize needs the frame size */
|
||||
cur_x += moveresize_client->frame->size.left +
|
||||
moveresize_client->frame->size.right;
|
||||
|
@ -173,8 +238,25 @@ static void do_resize()
|
|||
cur_y -= moveresize_client->frame->size.top +
|
||||
moveresize_client->frame->size.bottom;
|
||||
|
||||
client_configure(moveresize_client, lockcorner, moveresize_client->area.x,
|
||||
moveresize_client->area.y, cur_x, cur_y, TRUE, FALSE);
|
||||
oldx = moveresize_client->frame->area.x;
|
||||
oldy = moveresize_client->frame->area.y;
|
||||
oldw = moveresize_client->frame->area.width;
|
||||
oldh = moveresize_client->frame->area.height;
|
||||
client_configure(moveresize_client, lockcorner,
|
||||
moveresize_client->area.x, moveresize_client->area.y,
|
||||
cur_x, cur_y, TRUE, FALSE);
|
||||
/* draw the new one */
|
||||
if (!config_opaque_resize)
|
||||
XDrawRectangle(ob_display, opaque_window.win, opaque_gc,
|
||||
moveresize_client->frame->area.x,
|
||||
moveresize_client->frame->area.y,
|
||||
moveresize_client->frame->area.width - 1,
|
||||
moveresize_client->frame->area.height - 1);
|
||||
/* erase the old one */
|
||||
if (!config_opaque_resize && !first_draw)
|
||||
XDrawRectangle(ob_display, opaque_window.win, opaque_gc,
|
||||
oldx, oldy, oldw - 1, oldh - 1);
|
||||
first_draw = FALSE;
|
||||
|
||||
/* this would be better with a fixed width font ... XXX can do it better
|
||||
if there are 2 text boxes */
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
#include "openbox.h"
|
||||
#include "frame.h"
|
||||
#include "window.h"
|
||||
#include "stacking.h"
|
||||
#include "render/render.h"
|
||||
#include "render/theme.h"
|
||||
|
||||
typedef struct Popup {
|
||||
gboolean hasicon;
|
||||
ObWindow obwin;
|
||||
Window bg;
|
||||
|
||||
Window icon;
|
||||
Window text;
|
||||
|
||||
gboolean hasicon;
|
||||
Appearance *a_bg;
|
||||
Appearance *a_icon;
|
||||
Appearance *a_text;
|
||||
|
@ -16,16 +21,21 @@ typedef struct Popup {
|
|||
int y;
|
||||
int w;
|
||||
int h;
|
||||
gboolean mapped;
|
||||
} Popup;
|
||||
|
||||
Popup *popup_new(gboolean hasicon)
|
||||
{
|
||||
Popup *self = g_new(Popup, 1);
|
||||
self->obwin.type = Window_Internal;
|
||||
self->hasicon = hasicon;
|
||||
self->bg = None;
|
||||
self->a_text = NULL;
|
||||
self->gravity = NorthWestGravity;
|
||||
self->x = self->y = self->w = self->h = 0;
|
||||
self->mapped = FALSE;
|
||||
stacking_add(self);
|
||||
stacking_raise(INTERNAL_AS_WINDOW(self));
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -41,6 +51,7 @@ void popup_free(Popup *self)
|
|||
}
|
||||
if (self->a_text)
|
||||
appearance_free(self->a_text);
|
||||
stacking_remove(self);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
|
@ -206,10 +217,17 @@ void popup_show(Popup *self, char *text, Icon *icon)
|
|||
if (self->hasicon)
|
||||
paint(self->icon, self->a_icon);
|
||||
|
||||
XMapWindow(ob_display, self->bg);
|
||||
if (!self->mapped) {
|
||||
XMapWindow(ob_display, self->bg);
|
||||
stacking_raise(INTERNAL_AS_WINDOW(self));
|
||||
self->mapped = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void popup_hide(Popup *self)
|
||||
{
|
||||
XUnmapWindow(ob_display, self->bg);
|
||||
if (self->mapped) {
|
||||
XUnmapWindow(ob_display, self->bg);
|
||||
self->mapped = FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,26 @@ void stacking_set_list()
|
|||
windows = g_new(Window, size);
|
||||
win_it = windows;
|
||||
for (it = g_list_last(stacking_list); it != NULL;
|
||||
it = it->prev, ++win_it)
|
||||
if (WINDOW_IS_CLIENT(it->data))
|
||||
it = it->prev)
|
||||
if (WINDOW_IS_CLIENT(it->data)) {
|
||||
*win_it = window_top(it->data);
|
||||
++win_it;
|
||||
}
|
||||
} else
|
||||
windows = NULL;
|
||||
windows = win_it = NULL;
|
||||
|
||||
PROP_SETA32(ob_root, net_client_list_stacking, window,
|
||||
(guint32*)windows, size);
|
||||
(guint32*)windows, win_it - windows);
|
||||
|
||||
g_print("Client list:");
|
||||
for (it = client_list; it; it = it->next)
|
||||
g_print("0x%lx ", ((Client*)it->data)->window);
|
||||
g_print("\n");
|
||||
g_print("Stacking order: ");
|
||||
for (it = stacking_list; it; it = it->next)
|
||||
if (WINDOW_IS_CLIENT(it->data))
|
||||
g_print("0x%lx ", ((Client*)it->data)->window);
|
||||
g_print("\n");
|
||||
|
||||
if (windows)
|
||||
g_free(windows);
|
||||
|
|
|
@ -13,6 +13,8 @@ Window window_top(ObWindow *self)
|
|||
return ((Slit*)self)->frame;
|
||||
case Window_Client:
|
||||
return ((Client*)self)->frame->window;
|
||||
case Window_Internal:
|
||||
return ((InternalWindow*)self)->win;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
return None;
|
||||
|
@ -27,6 +29,8 @@ Window window_layer(ObWindow *self)
|
|||
return ((Slit*)self)->layer;
|
||||
case Window_Client:
|
||||
return ((Client*)self)->layer;
|
||||
case Window_Internal:
|
||||
return Layer_Internal;
|
||||
}
|
||||
g_assert_not_reached();
|
||||
return None;
|
||||
|
|
|
@ -6,16 +6,25 @@
|
|||
typedef enum {
|
||||
Window_Menu,
|
||||
Window_Slit,
|
||||
Window_Client
|
||||
Window_Client,
|
||||
Window_Internal
|
||||
} Window_InternalType;
|
||||
|
||||
typedef struct ObWindow {
|
||||
Window_InternalType type;
|
||||
} ObWindow;
|
||||
|
||||
/* Wrapper for internal stuff. If its struct matches this then it can be used
|
||||
as an ObWindow */
|
||||
typedef struct InternalWindow {
|
||||
ObWindow obwin;
|
||||
Window win;
|
||||
} InternalWindow;
|
||||
|
||||
#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)
|
||||
#define WINDOW_IS_INTERNAL(win) (((ObWindow*)win)->type == Window_Internal)
|
||||
|
||||
struct Menu;
|
||||
struct Slit;
|
||||
|
@ -24,10 +33,12 @@ 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 WINDOW_AS_INTERNAL(win) ((struct InternalWindow*)win)
|
||||
|
||||
#define MENU_AS_WINDOW(menu) ((ObWindow*)menu)
|
||||
#define SLIT_AS_WINDOW(slit) ((ObWindow*)slit)
|
||||
#define CLIENT_AS_WINDOW(client) ((ObWindow*)client)
|
||||
#define INTERNAL_AS_WINDOW(intern) ((ObWindow*)intern)
|
||||
|
||||
Window window_top(ObWindow *self);
|
||||
Window window_layer(ObWindow *self);
|
||||
|
|
Loading…
Reference in a new issue