add support for _NET_REQUEST_FRAME_EXTENTS
This commit is contained in:
parent
20eaccaba2
commit
7f262bc2a0
7 changed files with 188 additions and 141 deletions
211
openbox/client.c
211
openbox/client.c
|
@ -66,7 +66,7 @@ GList *client_list = NULL;
|
|||
|
||||
static GSList *client_destructors = NULL;
|
||||
|
||||
static void client_get_all(ObClient *self);
|
||||
static void client_get_all(ObClient *self, gboolean real);
|
||||
static void client_toggle_border(ObClient *self, gboolean show);
|
||||
static void client_get_startup_id(ObClient *self);
|
||||
static void client_get_session_ids(ObClient *self);
|
||||
|
@ -76,9 +76,7 @@ static void client_get_state(ObClient *self);
|
|||
static void client_get_layer(ObClient *self);
|
||||
static void client_get_shaped(ObClient *self);
|
||||
static void client_get_mwm_hints(ObClient *self);
|
||||
static void client_get_gravity(ObClient *self);
|
||||
static void client_get_colormap(ObClient *self);
|
||||
static void client_get_transientness(ObClient *self);
|
||||
static void client_change_allowed_actions(ObClient *self);
|
||||
static void client_change_state(ObClient *self);
|
||||
static void client_change_wm_state(ObClient *self);
|
||||
|
@ -236,8 +234,8 @@ void client_manage(Window window)
|
|||
|
||||
grab_server(TRUE);
|
||||
|
||||
/* check if it has already been unmapped by the time we started mapping.
|
||||
the grab does a sync so we don't have to here */
|
||||
/* check if it has already been unmapped by the time we started
|
||||
mapping. the grab does a sync so we don't have to here */
|
||||
if (XCheckTypedWindowEvent(ob_display, window, DestroyNotify, &e) ||
|
||||
XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e))
|
||||
{
|
||||
|
@ -277,7 +275,6 @@ void client_manage(Window window)
|
|||
XChangeWindowAttributes(ob_display, window,
|
||||
CWEventMask|CWDontPropagate, &attrib_set);
|
||||
|
||||
|
||||
/* create the ObClient struct, and populate it from the hints on the
|
||||
window */
|
||||
self = g_new0(ObClient, 1);
|
||||
|
@ -290,7 +287,7 @@ void client_manage(Window window)
|
|||
self->desktop = screen_num_desktops; /* always an invalid value */
|
||||
self->user_time = focus_client ? focus_client->user_time : CurrentTime;
|
||||
|
||||
client_get_all(self);
|
||||
client_get_all(self, TRUE);
|
||||
/* per-app settings override stuff, and return the settings for other
|
||||
uses too */
|
||||
settings = client_get_settings_state(self);
|
||||
|
@ -311,14 +308,14 @@ void client_manage(Window window)
|
|||
/* remove the client's border (and adjust re gravity) */
|
||||
client_toggle_border(self, FALSE);
|
||||
|
||||
/* specify that if we exit, the window should not be destroyed and should
|
||||
be reparented back to root automatically */
|
||||
/* specify that if we exit, the window should not be destroyed and
|
||||
should be reparented back to root automatically */
|
||||
XChangeSaveSet(ob_display, window, SetModeInsert);
|
||||
|
||||
/* create the decoration frame for the client window */
|
||||
self->frame = frame_new(self);
|
||||
|
||||
frame_grab_client(self->frame, self);
|
||||
frame_grab_client(self->frame);
|
||||
|
||||
/* do this after we have a frame.. it uses the frame to help determine the
|
||||
WM_STATE to apply. */
|
||||
|
@ -484,6 +481,31 @@ void client_manage(Window window)
|
|||
client_set_list();
|
||||
|
||||
ob_debug("Managed window 0x%lx (%s)\n", window, self->class);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ObClient *client_fake_manage(Window window)
|
||||
{
|
||||
ObClient *self;
|
||||
ObAppSettings *settings;
|
||||
|
||||
ob_debug("Pretend-managing window: %lx\n", window);
|
||||
|
||||
/* do this minimal stuff to figure out the client's decorations */
|
||||
|
||||
self = g_new0(ObClient, 1);
|
||||
self->window = window;
|
||||
|
||||
client_get_all(self, FALSE);
|
||||
/* per-app settings override stuff, and return the settings for other
|
||||
uses too */
|
||||
settings = client_get_settings_state(self);
|
||||
|
||||
/* create the decoration frame for the client window */
|
||||
self->frame = frame_new(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
void client_unmanage_all()
|
||||
|
@ -497,8 +519,8 @@ void client_unmanage(ObClient *self)
|
|||
guint j;
|
||||
GSList *it;
|
||||
|
||||
ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window, self->class,
|
||||
self->title ? self->title : "");
|
||||
ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window,
|
||||
self->class, self->title ? self->title : "");
|
||||
|
||||
g_assert(self != NULL);
|
||||
|
||||
|
@ -510,7 +532,8 @@ void client_unmanage(ObClient *self)
|
|||
/* flush to send the hide to the server quickly */
|
||||
XFlush(ob_display);
|
||||
|
||||
/* ignore enter events from the unmap so it doesnt mess with the focus */
|
||||
/* ignore enter events from the unmap so it doesnt mess with the
|
||||
focus */
|
||||
event_ignore_queued_enters();
|
||||
|
||||
mouse_grab_for_client(self, FALSE);
|
||||
|
@ -547,7 +570,7 @@ void client_unmanage(ObClient *self)
|
|||
for (it = self->group->members; it; it = g_slist_next(it))
|
||||
if (it->data != self)
|
||||
((ObClient*)it->data)->transients =
|
||||
g_slist_remove(((ObClient*)it->data)->transients, self);
|
||||
g_slist_remove(((ObClient*)it->data)->transients,self);
|
||||
} else if (self->transient_for) { /* transient of window */
|
||||
self->transient_for->transients =
|
||||
g_slist_remove(self->transient_for->transients, self);
|
||||
|
@ -594,7 +617,8 @@ void client_unmanage(ObClient *self)
|
|||
}
|
||||
|
||||
/* reparent the window out of the frame, and free the frame */
|
||||
frame_release_client(self->frame, self);
|
||||
frame_release_client(self->frame);
|
||||
frame_free(self->frame);
|
||||
self->frame = NULL;
|
||||
|
||||
if (ob_state() != OB_STATE_EXITING) {
|
||||
|
@ -604,11 +628,15 @@ void client_unmanage(ObClient *self)
|
|||
PROP_ERASE(self->window, net_wm_state);
|
||||
PROP_ERASE(self->window, wm_state);
|
||||
} else {
|
||||
/* if we're left in an unmapped state, the client wont be mapped. this
|
||||
is bad, since we will no longer be managing the window on restart */
|
||||
/* if we're left in an unmapped state, the client wont be mapped.
|
||||
this is bad, since we will no longer be managing the window on
|
||||
restart */
|
||||
XMapWindow(ob_display, self->window);
|
||||
}
|
||||
|
||||
/* update the list hints */
|
||||
client_set_list();
|
||||
|
||||
ob_debug("Unmanaged window 0x%lx\n", self->window);
|
||||
|
||||
/* free all data allocated in the client struct */
|
||||
|
@ -626,9 +654,14 @@ void client_unmanage(ObClient *self)
|
|||
g_free(self->client_machine);
|
||||
g_free(self->sm_client_id);
|
||||
g_free(self);
|
||||
|
||||
/* update the list hints */
|
||||
client_set_list();
|
||||
}
|
||||
|
||||
void client_fake_unmanage(ObClient *self)
|
||||
{
|
||||
/* this is all that got allocated to get the decorations */
|
||||
|
||||
frame_free(self->frame);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
static ObAppSettings *client_get_settings_state(ObClient *self)
|
||||
|
@ -949,68 +982,62 @@ static void client_toggle_border(ObClient *self, gboolean show)
|
|||
}
|
||||
|
||||
|
||||
static void client_get_all(ObClient *self)
|
||||
static void client_get_all(ObClient *self, gboolean real)
|
||||
{
|
||||
/* this is needed for the frame to set itself up */
|
||||
client_get_area(self);
|
||||
|
||||
/* these things can change the decor and functions of the window */
|
||||
|
||||
client_get_mwm_hints(self);
|
||||
|
||||
/* The transient-ness of a window is used to pick a type, but the type can
|
||||
also affect transiency.
|
||||
|
||||
Dialogs are always made transients for their group if they have one.
|
||||
|
||||
I also have made non-application type windows be transients for their
|
||||
group (eg utility windows).
|
||||
*/
|
||||
client_get_transientness(self);
|
||||
client_get_type(self);/* this can change the mwmhints for special cases */
|
||||
/* this can change the mwmhints for special cases */
|
||||
client_get_type_and_transientness(self);
|
||||
client_get_state(self);
|
||||
|
||||
client_update_wmhints(self);
|
||||
/* this may have already been called from client_update_wmhints */
|
||||
if (self->transient_for == NULL)
|
||||
client_update_transient_for(self);
|
||||
client_get_startup_id(self);
|
||||
client_get_desktop(self);/* uses transient data/group/startup id if a
|
||||
desktop is not specified */
|
||||
client_get_shaped(self);
|
||||
|
||||
client_get_layer(self); /* if layer hasn't been specified, get it from
|
||||
other sources if possible */
|
||||
|
||||
{
|
||||
/* a couple type-based defaults for new windows */
|
||||
|
||||
/* this makes sure that these windows appear on all desktops */
|
||||
if (self->type == OB_CLIENT_TYPE_DESKTOP)
|
||||
self->desktop = DESKTOP_ALL;
|
||||
}
|
||||
|
||||
client_update_protocols(self);
|
||||
|
||||
client_get_gravity(self); /* get the attribute gravity */
|
||||
client_update_normal_hints(self); /* this may override the attribute
|
||||
gravity */
|
||||
client_update_normal_hints(self);
|
||||
|
||||
/* got the type, the mwmhints, the protocols, and the normal hints
|
||||
(min/max sizes), so we're ready to set up the decorations/functions */
|
||||
client_setup_decor_and_functions(self);
|
||||
|
||||
if (real) {
|
||||
client_update_wmhints(self);
|
||||
/* this may have already been called from client_update_wmhints */
|
||||
if (self->transient_for == NULL)
|
||||
client_update_transient_for(self);
|
||||
|
||||
client_get_startup_id(self);
|
||||
client_get_desktop(self);/* uses transient data/group/startup id if a
|
||||
desktop is not specified */
|
||||
client_get_shaped(self);
|
||||
|
||||
client_get_layer(self); /* if layer hasn't been specified, get it from
|
||||
other sources if possible */
|
||||
|
||||
{
|
||||
/* a couple type-based defaults for new windows */
|
||||
|
||||
/* this makes sure that these windows appear on all desktops */
|
||||
if (self->type == OB_CLIENT_TYPE_DESKTOP)
|
||||
self->desktop = DESKTOP_ALL;
|
||||
}
|
||||
|
||||
#ifdef SYNC
|
||||
client_update_sync_request_counter(self);
|
||||
client_update_sync_request_counter(self);
|
||||
#endif
|
||||
|
||||
/* get the session related properties */
|
||||
client_get_session_ids(self);
|
||||
/* get the session related properties */
|
||||
client_get_session_ids(self);
|
||||
|
||||
client_get_colormap(self);
|
||||
client_update_title(self);
|
||||
client_update_strut(self);
|
||||
client_update_icons(self);
|
||||
client_update_user_time_window(self);
|
||||
if (!self->user_time_window) /* check if this would have been called */
|
||||
client_update_user_time(self);
|
||||
client_update_icon_geometry(self);
|
||||
client_get_colormap(self);
|
||||
client_update_title(self);
|
||||
client_update_strut(self);
|
||||
client_update_icons(self);
|
||||
client_update_user_time_window(self);
|
||||
if (!self->user_time_window) /* check if this would have been called */
|
||||
client_update_user_time(self);
|
||||
client_update_icon_geometry(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void client_get_startup_id(ObClient *self)
|
||||
|
@ -1170,20 +1197,12 @@ static void client_get_shaped(ObClient *self)
|
|||
#endif
|
||||
}
|
||||
|
||||
void client_get_transientness(ObClient *self)
|
||||
{
|
||||
Window t;
|
||||
if (XGetTransientForHint(ob_display, self->window, &t))
|
||||
self->transient = TRUE;
|
||||
}
|
||||
|
||||
void client_update_transient_for(ObClient *self)
|
||||
{
|
||||
Window t = None;
|
||||
ObClient *target = NULL;
|
||||
|
||||
if (XGetTransientForHint(ob_display, self->window, &t)) {
|
||||
self->transient = TRUE;
|
||||
if (t != self->window) { /* cant be transient to itself! */
|
||||
target = g_hash_table_lookup(window_map, &t);
|
||||
/* if this happens then we need to check for it*/
|
||||
|
@ -1220,16 +1239,8 @@ void client_update_transient_for(ObClient *self)
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (self->type == OB_CLIENT_TYPE_DIALOG ||
|
||||
self->type == OB_CLIENT_TYPE_TOOLBAR ||
|
||||
self->type == OB_CLIENT_TYPE_MENU ||
|
||||
self->type == OB_CLIENT_TYPE_UTILITY)
|
||||
{
|
||||
self->transient = TRUE;
|
||||
if (self->group)
|
||||
target = OB_TRAN_GROUP;
|
||||
} else
|
||||
self->transient = FALSE;
|
||||
} else if (self->transient && self->group)
|
||||
target = OB_TRAN_GROUP;
|
||||
|
||||
client_update_transient_tree(self, self->group, self->group,
|
||||
self->transient_for, target);
|
||||
|
@ -1364,12 +1375,14 @@ static void client_get_mwm_hints(ObClient *self)
|
|||
}
|
||||
}
|
||||
|
||||
void client_get_type(ObClient *self)
|
||||
void client_get_type_and_transientness(ObClient *self)
|
||||
{
|
||||
guint num, i;
|
||||
guint32 *val;
|
||||
Window t;
|
||||
|
||||
self->type = -1;
|
||||
self->transient = FALSE;
|
||||
|
||||
if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) {
|
||||
/* use the first value that we know about in the array */
|
||||
|
@ -1403,7 +1416,10 @@ void client_get_type(ObClient *self)
|
|||
}
|
||||
g_free(val);
|
||||
}
|
||||
|
||||
|
||||
if (XGetTransientForHint(ob_display, self->window, &t))
|
||||
self->transient = TRUE;
|
||||
|
||||
if (self->type == (ObClientType) -1) {
|
||||
/*the window type hint was not set, which means we either classify
|
||||
ourself as a normal window or a dialog, depending on if we are a
|
||||
|
@ -1413,6 +1429,15 @@ void client_get_type(ObClient *self)
|
|||
else
|
||||
self->type = OB_CLIENT_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
/* then, based on our type, we can update our transientness.. */
|
||||
if (self->type == OB_CLIENT_TYPE_DIALOG ||
|
||||
self->type == OB_CLIENT_TYPE_TOOLBAR ||
|
||||
self->type == OB_CLIENT_TYPE_MENU ||
|
||||
self->type == OB_CLIENT_TYPE_UTILITY)
|
||||
{
|
||||
self->transient = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void client_update_protocols(ObClient *self)
|
||||
|
@ -1456,16 +1481,6 @@ void client_update_sync_request_counter(ObClient *self)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void client_get_gravity(ObClient *self)
|
||||
{
|
||||
XWindowAttributes wattrib;
|
||||
Status ret;
|
||||
|
||||
ret = XGetWindowAttributes(ob_display, self->window, &wattrib);
|
||||
g_assert(ret != BadWindow);
|
||||
self->gravity = wattrib.win_gravity;
|
||||
}
|
||||
|
||||
void client_get_colormap(ObClient *self)
|
||||
{
|
||||
XWindowAttributes wa;
|
||||
|
|
|
@ -314,13 +314,22 @@ void client_remove_destructor(ObClientCallback func);
|
|||
|
||||
/*! Manages all existing windows */
|
||||
void client_manage_all();
|
||||
/*! Manages a given window */
|
||||
/*! Manages a given window
|
||||
*/
|
||||
void client_manage(Window win);
|
||||
/*! Unmanages all managed windows */
|
||||
void client_unmanage_all();
|
||||
/*! Unmanages a given client */
|
||||
void client_unmanage(ObClient *client);
|
||||
|
||||
/*! This manages a window only so far as is needed to get it's decorations.
|
||||
This is used when you want to determine a window's decorations before it
|
||||
is mapped. Call client_fake_unmanage() with the returned client when you
|
||||
are done with it. */
|
||||
ObClient *client_fake_manage(Window win);
|
||||
/*! Free the stuff created by client_fake_manage() */
|
||||
void client_fake_unmanage(ObClient *self);
|
||||
|
||||
/*! Sets the client list on the root window from the client_list */
|
||||
void client_set_list();
|
||||
|
||||
|
@ -354,7 +363,7 @@ gboolean client_focused(ObClient *self);
|
|||
|
||||
/*! Convery a position/size from a given gravity to the client's true gravity
|
||||
*/
|
||||
void client_convert_gravity(ObClient *client, gint gravity, gint *x, gint *y,
|
||||
void client_convert_gravity(ObClient *self, gint gravity, gint *x, gint *y,
|
||||
gint w, gint h);
|
||||
|
||||
#define client_move(self, x, y) \
|
||||
|
@ -536,7 +545,7 @@ void client_activate(ObClient *self, gboolean here, gboolean user);
|
|||
|
||||
/*! Bring all of its helper windows to its desktop. These are the utility and
|
||||
stuff windows. */
|
||||
void client_bring_helper_windows(ObClient *client);
|
||||
void client_bring_helper_windows(ObClient *self);
|
||||
|
||||
/*! Calculates the stacking layer for the client window */
|
||||
void client_calc_layer(ObClient *self);
|
||||
|
@ -600,8 +609,8 @@ void client_update_icon_geometry(ObClient *self);
|
|||
*/
|
||||
void client_setup_decor_and_functions(ObClient *self);
|
||||
|
||||
/*! Retrieves the window's type and sets ObClient->type */
|
||||
void client_get_type(ObClient *self);
|
||||
/*! Sets the window's type and transient flag */
|
||||
void client_get_type_and_transientness(ObClient *self);
|
||||
|
||||
const ObClientIcon *client_icon(ObClient *self, gint w, gint h);
|
||||
|
||||
|
|
|
@ -568,8 +568,32 @@ static void event_process(const XEvent *ec, gpointer data)
|
|||
event_handle_root(e);
|
||||
else if (e->type == MapRequest)
|
||||
client_manage(window);
|
||||
else if (e->type == ClientMessage) {
|
||||
/* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for
|
||||
windows that are not managed yet. */
|
||||
if (e->xclient.message_type == prop_atoms.net_request_frame_extents) {
|
||||
/* Pretend to manage the client, getting information used to
|
||||
determine its decorations */
|
||||
ObClient *c = client_fake_manage(e->xclient.window);
|
||||
gulong vals[4];
|
||||
|
||||
/* adjust the decorations so we know the sizes */
|
||||
frame_adjust_area(c->frame, FALSE, TRUE, TRUE);
|
||||
|
||||
/* set the frame extents on the window */
|
||||
vals[0] = c->frame->size.left;
|
||||
vals[1] = c->frame->size.right;
|
||||
vals[2] = c->frame->size.top;
|
||||
vals[3] = c->frame->size.bottom;
|
||||
PROP_SETA32(e->xclient.window, net_frame_extents,
|
||||
cardinal, vals, 4);
|
||||
|
||||
/* Free the pretend client */
|
||||
client_fake_unmanage(c);
|
||||
}
|
||||
}
|
||||
else if (e->type == ConfigureRequest) {
|
||||
/* unhandled configure requests must be used to configure the
|
||||
/* unhandled config5Aure requests must be used to configure the
|
||||
window directly */
|
||||
XWindowChanges xwc;
|
||||
|
||||
|
@ -1167,7 +1191,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
|
|||
client_update_wmhints(client);
|
||||
} else if (msgtype == XA_WM_TRANSIENT_FOR) {
|
||||
client_update_transient_for(client);
|
||||
client_get_type(client);
|
||||
client_get_type_and_transientness(client);
|
||||
/* type may have changed, so update the layer */
|
||||
client_calc_layer(client);
|
||||
client_setup_decor_and_functions(client);
|
||||
|
|
|
@ -99,6 +99,7 @@ ObFrame *frame_new(ObClient *client)
|
|||
Visual *visual;
|
||||
|
||||
self = g_new0(ObFrame, 1);
|
||||
self->client = client;
|
||||
|
||||
visual = check_32bit_client(client);
|
||||
|
||||
|
@ -245,7 +246,7 @@ static void free_theme_statics(ObFrame *self)
|
|||
RrAppearanceFree(self->a_icon);
|
||||
}
|
||||
|
||||
static void frame_free(ObFrame *self)
|
||||
void frame_free(ObFrame *self)
|
||||
{
|
||||
free_theme_statics(self);
|
||||
|
||||
|
@ -553,12 +554,10 @@ void frame_adjust_icon(ObFrame *self)
|
|||
framerender_frame(self);
|
||||
}
|
||||
|
||||
void frame_grab_client(ObFrame *self, ObClient *client)
|
||||
void frame_grab_client(ObFrame *self)
|
||||
{
|
||||
self->client = client;
|
||||
|
||||
/* reparent the client to the frame */
|
||||
XReparentWindow(ob_display, client->window, self->plate, 0, 0);
|
||||
XReparentWindow(ob_display, self->client->window, self->plate, 0, 0);
|
||||
/*
|
||||
When reparenting the client window, it is usually not mapped yet, since
|
||||
this occurs from a MapRequest. However, in the case where Openbox is
|
||||
|
@ -568,52 +567,50 @@ void frame_grab_client(ObFrame *self, ObClient *client)
|
|||
handled and need to be ignored.
|
||||
*/
|
||||
if (ob_state() == OB_STATE_STARTING)
|
||||
client->ignore_unmaps += 2;
|
||||
self->client->ignore_unmaps += 2;
|
||||
|
||||
/* select the event mask on the client's parent (to receive config/map
|
||||
req's) the ButtonPress is to catch clicks on the client border */
|
||||
XSelectInput(ob_display, self->plate, PLATE_EVENTMASK);
|
||||
|
||||
/* map the client so it maps when the frame does */
|
||||
XMapWindow(ob_display, client->window);
|
||||
XMapWindow(ob_display, self->client->window);
|
||||
|
||||
/* adjust the frame to the client's size */
|
||||
frame_adjust_area(self, FALSE, TRUE, FALSE);
|
||||
|
||||
/* set all the windows for the frame in the window_map */
|
||||
g_hash_table_insert(window_map, &self->window, client);
|
||||
g_hash_table_insert(window_map, &self->plate, client);
|
||||
g_hash_table_insert(window_map, &self->inner, client);
|
||||
g_hash_table_insert(window_map, &self->title, client);
|
||||
g_hash_table_insert(window_map, &self->label, client);
|
||||
g_hash_table_insert(window_map, &self->max, client);
|
||||
g_hash_table_insert(window_map, &self->close, client);
|
||||
g_hash_table_insert(window_map, &self->desk, client);
|
||||
g_hash_table_insert(window_map, &self->shade, client);
|
||||
g_hash_table_insert(window_map, &self->icon, client);
|
||||
g_hash_table_insert(window_map, &self->iconify, client);
|
||||
g_hash_table_insert(window_map, &self->handle, client);
|
||||
g_hash_table_insert(window_map, &self->lgrip, client);
|
||||
g_hash_table_insert(window_map, &self->rgrip, client);
|
||||
g_hash_table_insert(window_map, &self->tltresize, client);
|
||||
g_hash_table_insert(window_map, &self->tllresize, client);
|
||||
g_hash_table_insert(window_map, &self->trtresize, client);
|
||||
g_hash_table_insert(window_map, &self->trrresize, client);
|
||||
g_hash_table_insert(window_map, &self->window, self->client);
|
||||
g_hash_table_insert(window_map, &self->plate, self->client);
|
||||
g_hash_table_insert(window_map, &self->inner, self->client);
|
||||
g_hash_table_insert(window_map, &self->title, self->client);
|
||||
g_hash_table_insert(window_map, &self->label, self->client);
|
||||
g_hash_table_insert(window_map, &self->max, self->client);
|
||||
g_hash_table_insert(window_map, &self->close, self->client);
|
||||
g_hash_table_insert(window_map, &self->desk, self->client);
|
||||
g_hash_table_insert(window_map, &self->shade, self->client);
|
||||
g_hash_table_insert(window_map, &self->icon, self->client);
|
||||
g_hash_table_insert(window_map, &self->iconify, self->client);
|
||||
g_hash_table_insert(window_map, &self->handle, self->client);
|
||||
g_hash_table_insert(window_map, &self->lgrip, self->client);
|
||||
g_hash_table_insert(window_map, &self->rgrip, self->client);
|
||||
g_hash_table_insert(window_map, &self->tltresize, self->client);
|
||||
g_hash_table_insert(window_map, &self->tllresize, self->client);
|
||||
g_hash_table_insert(window_map, &self->trtresize, self->client);
|
||||
g_hash_table_insert(window_map, &self->trrresize, self->client);
|
||||
}
|
||||
|
||||
void frame_release_client(ObFrame *self, ObClient *client)
|
||||
void frame_release_client(ObFrame *self)
|
||||
{
|
||||
XEvent ev;
|
||||
gboolean reparent = TRUE;
|
||||
|
||||
g_assert(self->client == client);
|
||||
|
||||
/* if there was any animation going on, kill it */
|
||||
ob_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
|
||||
self, FALSE);
|
||||
|
||||
/* check if the app has already reparented its window away */
|
||||
while (XCheckTypedWindowEvent(ob_display, client->window,
|
||||
while (XCheckTypedWindowEvent(ob_display, self->client->window,
|
||||
ReparentNotify, &ev))
|
||||
{
|
||||
/* This check makes sure we don't catch our own reparent action to
|
||||
|
@ -633,10 +630,10 @@ void frame_release_client(ObFrame *self, ObClient *client)
|
|||
if (reparent) {
|
||||
/* according to the ICCCM - if the client doesn't reparent itself,
|
||||
then we will reparent the window to root for them */
|
||||
XReparentWindow(ob_display, client->window,
|
||||
XReparentWindow(ob_display, self->client->window,
|
||||
RootWindow(ob_display, ob_screen),
|
||||
client->area.x,
|
||||
client->area.y);
|
||||
self->client->area.x,
|
||||
self->client->area.y);
|
||||
}
|
||||
|
||||
/* remove all the windows for the frame from the window_map */
|
||||
|
@ -660,8 +657,6 @@ void frame_release_client(ObFrame *self, ObClient *client)
|
|||
g_hash_table_remove(window_map, &self->trrresize);
|
||||
|
||||
ob_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
|
||||
|
||||
frame_free(self);
|
||||
}
|
||||
|
||||
/* is there anything present between us and the label? */
|
||||
|
|
|
@ -162,6 +162,8 @@ struct _ObFrame
|
|||
};
|
||||
|
||||
ObFrame *frame_new(struct _ObClient *c);
|
||||
void frame_free(ObFrame *self);
|
||||
|
||||
void frame_show(ObFrame *self);
|
||||
void frame_hide(ObFrame *self);
|
||||
void frame_adjust_theme(ObFrame *self);
|
||||
|
@ -173,8 +175,8 @@ void frame_adjust_state(ObFrame *self);
|
|||
void frame_adjust_focus(ObFrame *self, gboolean hilite);
|
||||
void frame_adjust_title(ObFrame *self);
|
||||
void frame_adjust_icon(ObFrame *self);
|
||||
void frame_grab_client(ObFrame *self, struct _ObClient *client);
|
||||
void frame_release_client(ObFrame *self, struct _ObClient *client);
|
||||
void frame_grab_client(ObFrame *self);
|
||||
void frame_release_client(ObFrame *self);
|
||||
|
||||
ObFrameContext frame_context_from_string(const gchar *name);
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ typedef struct Atoms {
|
|||
Atom net_wm_user_time;
|
||||
Atom net_wm_user_time_window;
|
||||
Atom net_frame_extents;
|
||||
Atom net_request_frame_extents;
|
||||
|
||||
/* application protocols */
|
||||
/* Atom net_wm_ping; */
|
||||
|
|
|
@ -275,6 +275,7 @@ gboolean screen_annex(const gchar *program_name)
|
|||
supported[i++] = prop_atoms.net_wm_user_time;
|
||||
supported[i++] = prop_atoms.net_wm_user_time_window;
|
||||
supported[i++] = prop_atoms.net_frame_extents;
|
||||
supported[i++] = prop_atoms.net_request_frame_extents;
|
||||
supported[i++] = prop_atoms.net_startup_id;
|
||||
#ifdef SYNC
|
||||
supported[i++] = prop_atoms.net_wm_sync_request;
|
||||
|
|
Loading…
Reference in a new issue