summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2007-05-09 20:13:20 +0000
committerDana Jansens <danakj@orodu.net>2007-05-09 20:13:20 +0000
commit7f262bc2a0733a77ae5a30752aecdcf4ba35f223 (patch)
tree51f028c2748ed8a0f1360a8ae6f73eb57e6f62d2 /openbox
parent20eaccaba2020e8396c0c9d9ad1282bf5d2ad95d (diff)
add support for _NET_REQUEST_FRAME_EXTENTS
Diffstat (limited to 'openbox')
-rw-r--r--openbox/client.c207
-rw-r--r--openbox/client.h19
-rw-r--r--openbox/event.c28
-rw-r--r--openbox/frame.c63
-rw-r--r--openbox/frame.h6
-rw-r--r--openbox/prop.h1
-rw-r--r--openbox/screen.c1
7 files changed, 186 insertions, 139 deletions
diff --git a/openbox/client.c b/openbox/client.c
index 3f3f161d..83c59030 100644
--- a/openbox/client.c
+++ b/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);
- 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.
+ /* these things can change the decor and functions of the window */
- 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 */
+ client_get_mwm_hints(self);
+ /* this can change the mwmhints for special cases */
+ client_get_type_and_transientness(self);
client_get_state(self);
+ client_update_protocols(self);
+ client_update_normal_hints(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);
+ /* 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);
- client_get_layer(self); /* if layer hasn't been specified, get it from
- other sources if possible */
+ 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);
- {
- /* a couple type-based defaults for new windows */
+ 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);
- /* 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_layer(self); /* if layer hasn't been specified, get it from
+ other sources if possible */
- client_get_gravity(self); /* get the attribute gravity */
- client_update_normal_hints(self); /* this may override the attribute
- gravity */
+ {
+ /* a couple type-based defaults for new windows */
- /* 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);
+ /* 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;
diff --git a/openbox/client.h b/openbox/client.h
index f9a19483..30d40510 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -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);
diff --git a/openbox/event.c b/openbox/event.c
index babb5197..fe06935d 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -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);
diff --git a/openbox/frame.c b/openbox/frame.c
index 2c3fb58f..dd24f5ca 100644
--- a/openbox/frame.c
+++ b/openbox/frame.c
@@ -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? */
diff --git a/openbox/frame.h b/openbox/frame.h
index 3a5dfdb2..147f59de 100644
--- a/openbox/frame.h
+++ b/openbox/frame.h
@@ -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);
diff --git a/openbox/prop.h b/openbox/prop.h
index f8b44a73..4f45b6d4 100644
--- a/openbox/prop.h
+++ b/openbox/prop.h
@@ -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; */
diff --git a/openbox/screen.c b/openbox/screen.c
index 9265c73b..190468aa 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -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;