#include "window.h"
#include "event.h"
#include "debug.h"
+#include "dock.h"
#include "obt/prop.h"
GList *stacking_list = NULL;
stacking_list_tail = g_list_last(stacking_list);
}
+void stacking_above(ObWindow *window, ObWindow *above)
+{
+ GList *wins, *before;
+
+ if (window_layer(window) != window_layer(above))
+ return;
+
+ wins = g_list_append(NULL, window);
+ stacking_list = g_list_remove(stacking_list, window);
+ before = g_list_previous(g_list_find(stacking_list, above));
+ do_restack(wins, before);
+ g_list_free(wins);
+}
+
void stacking_below(ObWindow *window, ObWindow *below)
{
GList *wins, *before;
stacking_list_tail = g_list_last(stacking_list);
}
-/*! Returns TRUE if client is occluded by the sibling. If sibling is NULL it
- tries against all other clients.
-*/
-static gboolean stacking_occluded(ObClient *client, ObClient *sibling)
+ObWindow *stacking_occluded(ObClient *client, ObWindow *sibling_win)
{
GList *it;
- gboolean occluded = FALSE;
- gboolean found = FALSE;
+ ObWindow *occluded = NULL;
+ ObClient *sibling = NULL;
+
+ if (sibling_win && WINDOW_IS_CLIENT(sibling_win))
+ sibling = WINDOW_AS_CLIENT(sibling_win);
/* no need for any looping in this case */
if (sibling && client->layer != sibling->layer)
- return occluded;
+ return NULL;
- for (it = stacking_list; it;
- it = (found ? g_list_previous(it) :g_list_next(it)))
+ for (it = g_list_previous(g_list_find(stacking_list, client)); it;
+ it = g_list_previous(it))
if (WINDOW_IS_CLIENT(it->data)) {
ObClient *c = it->data;
- if (found && !c->iconic &&
+ if (!c->iconic &&
(c->desktop == DESKTOP_ALL || client->desktop == DESKTOP_ALL ||
c->desktop == client->desktop) &&
!client_search_transient(client, c))
{
if (sibling != NULL) {
if (c == sibling) {
- occluded = TRUE;
+ occluded = sibling_win;
break;
}
}
else if (c->layer == client->layer) {
- occluded = TRUE;
+ occluded = CLIENT_AS_WINDOW(c);
break;
}
else if (c->layer > client->layer)
break; /* we past its layer */
}
}
- else if (c == client)
- found = TRUE;
+ }
+ else if (WINDOW_IS_DOCK(it->data)) {
+ ObDock *dock = it->data;
+ if (RECT_INTERSECTS_RECT(dock->area, client->frame->area))
+ {
+ if (sibling_win != NULL) {
+ if (DOCK_AS_WINDOW(dock) == sibling_win) {
+ occluded = sibling_win;
+ break;
+ }
+ }
+ else
+ occluded = DOCK_AS_WINDOW(dock);
+ }
}
return occluded;
}
-/*! Returns TRUE if client occludes the sibling. If sibling is NULL it tries
- against all other clients.
-*/
-static gboolean stacking_occludes(ObClient *client, ObClient *sibling)
+ObWindow *stacking_occludes(ObClient *client, ObWindow *sibling_win)
{
GList *it;
- gboolean occludes = FALSE;
- gboolean found = FALSE;
+ ObWindow *occludes = NULL;
+ ObClient *sibling = NULL;
+
+ if (sibling_win && WINDOW_IS_CLIENT(sibling_win))
+ sibling = WINDOW_AS_CLIENT(sibling_win);
/* no need for any looping in this case */
if (sibling && client->layer != sibling->layer)
- return occludes;
+ return NULL;
- for (it = stacking_list; it; it = g_list_next(it))
+ for (it = g_list_next(g_list_find(stacking_list, client));
+ it; it = g_list_next(it))
if (WINDOW_IS_CLIENT(it->data)) {
ObClient *c = it->data;
- if (found && !c->iconic &&
+ if (!c->iconic &&
(c->desktop == DESKTOP_ALL || client->desktop == DESKTOP_ALL ||
c->desktop == client->desktop) &&
!client_search_transient(c, client))
{
if (sibling != NULL) {
if (c == sibling) {
- occludes = TRUE;
+ occludes = sibling_win;
break;
}
}
else if (c->layer == client->layer) {
- occludes = TRUE;
+ occludes = CLIENT_AS_WINDOW(c);
break;
}
else if (c->layer < client->layer)
break; /* we past its layer */
}
}
- else if (c == client)
- found = TRUE;
+ }
+ else if (WINDOW_IS_DOCK(it->data)) {
+ ObDock *dock = it->data;
+ if (RECT_INTERSECTS_RECT(dock->area, client->frame->area))
+ {
+ if (sibling_win != NULL) {
+ if (DOCK_AS_WINDOW(dock) == sibling_win) {
+ occludes = sibling_win;
+ break;
+ }
+ }
+ else
+ occludes = DOCK_AS_WINDOW(dock);
+ }
}
return occludes;
}
-gboolean stacking_restack_request(ObClient *client, ObClient *sibling,
+gboolean stacking_restack_request(ObClient *client, ObWindow *sibling_win,
gint detail)
{
gboolean ret = FALSE;
+ ObClient *sibling = NULL;
+
+ if (sibling_win && WINDOW_IS_CLIENT(sibling_win))
+ sibling = WINDOW_AS_CLIENT(sibling_win);
+
if (sibling && ((client->desktop != sibling->desktop &&
client->desktop != DESKTOP_ALL &&
sibling->desktop != DESKTOP_ALL) ||
client->title, sibling ? sibling->title : "(all)");
/* if this client occludes sibling (or anything if NULL), then
lower it to the bottom */
- if (stacking_occludes(client, sibling)) {
+ if (stacking_occludes(client, sibling_win)) {
stacking_lower(CLIENT_AS_WINDOW(client));
ret = TRUE;
}
case TopIf:
ob_debug("Restack request TopIf for client %s sibling %s",
client->title, sibling ? sibling->title : "(all)");
- if (stacking_occluded(client, sibling)) {
+ if (stacking_occluded(client, sibling_win)) {
stacking_raise(CLIENT_AS_WINDOW(client));
ret = TRUE;
}
case Opposite:
ob_debug("Restack request Opposite for client %s sibling %s",
client->title, sibling ? sibling->title : "(all)");
- if (stacking_occluded(client, sibling)) {
+ if (stacking_occluded(client, sibling_win)) {
stacking_raise(CLIENT_AS_WINDOW(client));
ret = TRUE;
}
- else if (stacking_occludes(client, sibling)) {
+ else if (stacking_occludes(client, sibling_win)) {
stacking_lower(CLIENT_AS_WINDOW(client));
ret = TRUE;
}