add support for _NET_RESTACK_WINDOW
This commit is contained in:
parent
ae4bb6bcb2
commit
c2c84c3f5e
6 changed files with 99 additions and 43 deletions
|
@ -1026,50 +1026,12 @@ static void event_handle_client(ObClient *client, XEvent *e)
|
|||
ObWindow *win;
|
||||
win = g_hash_table_lookup(window_map,
|
||||
&e->xconfigurerequest.above);
|
||||
if (WINDOW_IS_CLIENT(win))
|
||||
if (WINDOW_IS_CLIENT(win) && WINDOW_AS_CLIENT(win) != client)
|
||||
sibling = WINDOW_AS_CLIENT(win);
|
||||
}
|
||||
|
||||
switch (e->xconfigurerequest.detail) {
|
||||
case Below:
|
||||
ob_debug("ConfigureRequest Below for client %s sibling %s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
/* just lower it */
|
||||
stacking_lower(CLIENT_AS_WINDOW(client));
|
||||
break;
|
||||
case BottomIf:
|
||||
ob_debug("ConfigureRequest BottomIf for client %s sibling "
|
||||
"%s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
/* if this client occludes sibling (or anything if NULL), then
|
||||
lower it to the bottom */
|
||||
if (stacking_occluded(sibling, client))
|
||||
stacking_lower(CLIENT_AS_WINDOW(client));
|
||||
break;
|
||||
case Above:
|
||||
ob_debug("ConfigureRequest Above for client %s sibling %s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
/* activate it rather than just focus it */
|
||||
client_activate(client, FALSE, FALSE);
|
||||
break;
|
||||
case TopIf:
|
||||
ob_debug("ConfigureRequest TopIf for client %s sibling %s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
if (stacking_occluded(client, sibling))
|
||||
/* activate it rather than just focus it */
|
||||
client_activate(client, FALSE, FALSE);
|
||||
case Opposite:
|
||||
ob_debug("ConfigureRequest Opposite for client %s sibling "
|
||||
"%s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
if (stacking_occluded(client, sibling))
|
||||
/* activate it rather than just focus it */
|
||||
client_activate(client, FALSE, FALSE);
|
||||
else if (stacking_occluded(sibling, client))
|
||||
stacking_lower(CLIENT_AS_WINDOW(client));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
stacking_restack_request(client, sibling,
|
||||
e->xconfigurerequest.detail);
|
||||
}
|
||||
break;
|
||||
case UnmapNotify:
|
||||
|
@ -1246,6 +1208,41 @@ static void event_handle_client(ObClient *client, XEvent *e)
|
|||
client_convert_gravity(client, grav, &x, &y, w, h);
|
||||
client_find_onscreen(client, &x, &y, w, h, FALSE);
|
||||
client_configure(client, x, y, w, h, FALSE, TRUE);
|
||||
} else if (msgtype == prop_atoms.net_restack_window) {
|
||||
if (e->xclient.data.l[0] != 2) {
|
||||
ob_debug_type(OB_DEBUG_APP_BUGS,
|
||||
"_NET_RESTACK_WINDOW sent for window %s with "
|
||||
"invalid source indication %ld\n",
|
||||
client->title, e->xclient.data.l[0]);
|
||||
} else {
|
||||
ObClient *sibling = NULL;
|
||||
if (e->xclient.data.l[1]) {
|
||||
ObWindow *win = g_hash_table_lookup(window_map,
|
||||
&e->xclient.data.l[1]);
|
||||
if (WINDOW_IS_CLIENT(win) &&
|
||||
WINDOW_AS_CLIENT(win) != client)
|
||||
{
|
||||
sibling = WINDOW_AS_CLIENT(win);
|
||||
}
|
||||
if (sibling == NULL)
|
||||
ob_debug_type(OB_DEBUG_APP_BUGS,
|
||||
"_NET_RESTACK_WINDOW sent for window %s "
|
||||
"with invalid sibling 0x%x\n",
|
||||
client->title, e->xclient.data.l[1]);
|
||||
}
|
||||
if (e->xclient.data.l[2] == Below ||
|
||||
e->xclient.data.l[2] == BottomIf ||
|
||||
e->xclient.data.l[2] == Above ||
|
||||
e->xclient.data.l[2] == TopIf ||
|
||||
e->xclient.data.l[2] == Opposite)
|
||||
{
|
||||
stacking_restack_request(client, sibling,
|
||||
e->xclient.data.l[2]);
|
||||
}
|
||||
ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_RESTACK_WINDOW sent "
|
||||
"for window %s with invalid detail 0d\n",
|
||||
client->title, e->xclient.data.l[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PropertyNotify:
|
||||
|
|
|
@ -75,6 +75,8 @@ void prop_startup()
|
|||
CREATE(net_close_window, "_NET_CLOSE_WINDOW");
|
||||
CREATE(net_wm_moveresize, "_NET_WM_MOVERESIZE");
|
||||
CREATE(net_moveresize_window, "_NET_MOVERESIZE_WINDOW");
|
||||
CREATE(net_request_frame_extents, "_NET_REQUEST_FRAME_EXTENTS");
|
||||
CREATE(net_restack_window, "_NET_RESTACK_WINDOW");
|
||||
|
||||
CREATE(net_startup_id, "_NET_STARTUP_ID");
|
||||
|
||||
|
@ -95,7 +97,6 @@ void prop_startup()
|
|||
CREATE(net_wm_user_time_window, "_NET_WM_USER_TIME_WINDOW");
|
||||
CREATE(kde_net_wm_frame_strut, "_KDE_NET_WM_FRAME_STRUT");
|
||||
CREATE(net_frame_extents, "_NET_FRAME_EXTENTS");
|
||||
CREATE(net_request_frame_extents, "_NET_REQUEST_FRAME_EXTENTS");
|
||||
|
||||
/* CREATE(net_wm_ping, "_NET_WM_PING"); */
|
||||
#ifdef SYNC
|
||||
|
|
|
@ -108,6 +108,8 @@ typedef struct Atoms {
|
|||
Atom net_close_window;
|
||||
Atom net_wm_moveresize;
|
||||
Atom net_moveresize_window;
|
||||
Atom net_request_frame_extents;
|
||||
Atom net_restack_window;
|
||||
|
||||
/* helpful hints to apps that aren't used for anything */
|
||||
Atom net_wm_full_placement;
|
||||
|
@ -132,7 +134,6 @@ 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; */
|
||||
|
|
|
@ -276,6 +276,7 @@ gboolean screen_annex(const gchar *program_name)
|
|||
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_restack_window;
|
||||
supported[i++] = prop_atoms.net_startup_id;
|
||||
#ifdef SYNC
|
||||
supported[i++] = prop_atoms.net_wm_sync_request;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "group.h"
|
||||
#include "frame.h"
|
||||
#include "window.h"
|
||||
#include "debug.h"
|
||||
|
||||
GList *stacking_list = NULL;
|
||||
|
||||
|
@ -492,3 +493,46 @@ gboolean stacking_occluded(ObClient *client, ObClient *sibling)
|
|||
}
|
||||
return obscured;
|
||||
}
|
||||
|
||||
void stacking_restack_request(ObClient *client, ObClient *sibling,
|
||||
gint detail)
|
||||
{
|
||||
switch (detail) {
|
||||
case Below:
|
||||
ob_debug("Restack request Below for client %s sibling %s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
/* just lower it */
|
||||
stacking_lower(CLIENT_AS_WINDOW(client));
|
||||
break;
|
||||
case BottomIf:
|
||||
ob_debug("Restack request BottomIf for client %s sibling "
|
||||
"%s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
/* if this client occludes sibling (or anything if NULL), then
|
||||
lower it to the bottom */
|
||||
if (stacking_occluded(sibling, client))
|
||||
stacking_lower(CLIENT_AS_WINDOW(client));
|
||||
break;
|
||||
case Above:
|
||||
ob_debug("Restack request Above for client %s sibling %s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
/* activate it rather than just focus it */
|
||||
client_activate(client, FALSE, FALSE);
|
||||
break;
|
||||
case TopIf:
|
||||
ob_debug("Restack request TopIf for client %s sibling %s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
if (stacking_occluded(client, sibling))
|
||||
/* activate it rather than just focus it */
|
||||
client_activate(client, FALSE, FALSE);
|
||||
case Opposite:
|
||||
ob_debug("Restack request Opposite for client %s sibling "
|
||||
"%s\n",
|
||||
client->title, sibling ? sibling->title : "(all)");
|
||||
if (stacking_occluded(client, sibling))
|
||||
/* activate it rather than just focus it */
|
||||
client_activate(client, FALSE, FALSE);
|
||||
else if (stacking_occluded(sibling, client))
|
||||
stacking_lower(CLIENT_AS_WINDOW(client));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,4 +64,16 @@ void stacking_below(ObWindow *window, ObWindow *below);
|
|||
*/
|
||||
gboolean stacking_occluded(struct _ObClient *client,struct _ObClient *sibling);
|
||||
|
||||
/*! Restack a window based upon a sibling (or all windows) in various ways.
|
||||
@param client The client to be restacked
|
||||
@param sibling Another client to compare to, or NULL to compare to all
|
||||
windows
|
||||
@param detail One of Above, Below, TopIf, BottomIf, Opposite
|
||||
See http://tronche.com/gui/x/xlib/window/configure.html for details on
|
||||
how each detail works with and without a sibling.
|
||||
*/
|
||||
void stacking_restack_request(struct _ObClient *client,
|
||||
struct _ObClient *sibling,
|
||||
gint detail);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue