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;
|
ObWindow *win;
|
||||||
win = g_hash_table_lookup(window_map,
|
win = g_hash_table_lookup(window_map,
|
||||||
&e->xconfigurerequest.above);
|
&e->xconfigurerequest.above);
|
||||||
if (WINDOW_IS_CLIENT(win))
|
if (WINDOW_IS_CLIENT(win) && WINDOW_AS_CLIENT(win) != client)
|
||||||
sibling = WINDOW_AS_CLIENT(win);
|
sibling = WINDOW_AS_CLIENT(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (e->xconfigurerequest.detail) {
|
stacking_restack_request(client, sibling,
|
||||||
case Below:
|
e->xconfigurerequest.detail);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UnmapNotify:
|
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_convert_gravity(client, grav, &x, &y, w, h);
|
||||||
client_find_onscreen(client, &x, &y, w, h, FALSE);
|
client_find_onscreen(client, &x, &y, w, h, FALSE);
|
||||||
client_configure(client, x, y, w, h, FALSE, TRUE);
|
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;
|
break;
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
|
|
|
@ -75,6 +75,8 @@ void prop_startup()
|
||||||
CREATE(net_close_window, "_NET_CLOSE_WINDOW");
|
CREATE(net_close_window, "_NET_CLOSE_WINDOW");
|
||||||
CREATE(net_wm_moveresize, "_NET_WM_MOVERESIZE");
|
CREATE(net_wm_moveresize, "_NET_WM_MOVERESIZE");
|
||||||
CREATE(net_moveresize_window, "_NET_MOVERESIZE_WINDOW");
|
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");
|
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(net_wm_user_time_window, "_NET_WM_USER_TIME_WINDOW");
|
||||||
CREATE(kde_net_wm_frame_strut, "_KDE_NET_WM_FRAME_STRUT");
|
CREATE(kde_net_wm_frame_strut, "_KDE_NET_WM_FRAME_STRUT");
|
||||||
CREATE(net_frame_extents, "_NET_FRAME_EXTENTS");
|
CREATE(net_frame_extents, "_NET_FRAME_EXTENTS");
|
||||||
CREATE(net_request_frame_extents, "_NET_REQUEST_FRAME_EXTENTS");
|
|
||||||
|
|
||||||
/* CREATE(net_wm_ping, "_NET_WM_PING"); */
|
/* CREATE(net_wm_ping, "_NET_WM_PING"); */
|
||||||
#ifdef SYNC
|
#ifdef SYNC
|
||||||
|
|
|
@ -108,6 +108,8 @@ typedef struct Atoms {
|
||||||
Atom net_close_window;
|
Atom net_close_window;
|
||||||
Atom net_wm_moveresize;
|
Atom net_wm_moveresize;
|
||||||
Atom net_moveresize_window;
|
Atom net_moveresize_window;
|
||||||
|
Atom net_request_frame_extents;
|
||||||
|
Atom net_restack_window;
|
||||||
|
|
||||||
/* helpful hints to apps that aren't used for anything */
|
/* helpful hints to apps that aren't used for anything */
|
||||||
Atom net_wm_full_placement;
|
Atom net_wm_full_placement;
|
||||||
|
@ -132,7 +134,6 @@ typedef struct Atoms {
|
||||||
Atom net_wm_user_time;
|
Atom net_wm_user_time;
|
||||||
Atom net_wm_user_time_window;
|
Atom net_wm_user_time_window;
|
||||||
Atom net_frame_extents;
|
Atom net_frame_extents;
|
||||||
Atom net_request_frame_extents;
|
|
||||||
|
|
||||||
/* application protocols */
|
/* application protocols */
|
||||||
/* Atom net_wm_ping; */
|
/* 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_wm_user_time_window;
|
||||||
supported[i++] = prop_atoms.net_frame_extents;
|
supported[i++] = prop_atoms.net_frame_extents;
|
||||||
supported[i++] = prop_atoms.net_request_frame_extents;
|
supported[i++] = prop_atoms.net_request_frame_extents;
|
||||||
|
supported[i++] = prop_atoms.net_restack_window;
|
||||||
supported[i++] = prop_atoms.net_startup_id;
|
supported[i++] = prop_atoms.net_startup_id;
|
||||||
#ifdef SYNC
|
#ifdef SYNC
|
||||||
supported[i++] = prop_atoms.net_wm_sync_request;
|
supported[i++] = prop_atoms.net_wm_sync_request;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
GList *stacking_list = NULL;
|
GList *stacking_list = NULL;
|
||||||
|
|
||||||
|
@ -492,3 +493,46 @@ gboolean stacking_occluded(ObClient *client, ObClient *sibling)
|
||||||
}
|
}
|
||||||
return obscured;
|
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);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue