add support for _NET_RESTACK_WINDOW

This commit is contained in:
Dana Jansens 2007-05-10 04:06:50 +00:00
parent ae4bb6bcb2
commit c2c84c3f5e
6 changed files with 99 additions and 43 deletions

View file

@ -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:

View file

@ -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

View file

@ -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; */

View file

@ -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;

View file

@ -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));
}
}

View file

@ -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