The attached patches make icons and the dock declare their own
partial struts if the "do not cover" preferences are active.
The actual user experience should remain the same until we can
revamp screen usable area. I have a few ideas for that...
>From a60c65ce086bebaa312cb996748dce78ef1a4995 Mon Sep 17 00:00:00 2001
From: Iain Patterson <[email protected]>
Date: Mon, 29 Oct 2012 15:35:56 -0700
Subject: [PATCH 1/3] AppIcon helper functions.
Create wAppIconFor() and wAppIconTouchesHead() to match wWindowFor()
and wWindowTouchesHead(). These functions will allow us to locate the
window and head associated with a particular app icon or dock icon.
---
src/appicon.c | 17 +++++++++++++++++
src/appicon.h | 1 +
src/xinerama.c | 19 +++++++++++++++++++
src/xinerama.h | 2 ++
4 files changed, 39 insertions(+)
diff --git a/src/appicon.c b/src/appicon.c
index 9bac0ef..6be3057 100644
--- a/src/appicon.c
+++ b/src/appicon.c
@@ -60,6 +60,7 @@
extern Cursor wCursor[WCUR_LAST];
extern WPreferences wPreferences;
extern WDDomain *WDWindowAttributes;
+extern XContext wWinContext;
#define MOD_MASK wPreferences.modifier_mask
@@ -1016,3 +1017,19 @@ static void remove_from_appicon_list(WScreen *scr, WAppIcon *appicon)
appicon->prev = NULL;
appicon->next = NULL;
}
+
+WAppIcon *wAppIconFor(Window window)
+{
+ WObjDescriptor *desc;
+
+ if (window == None)
+ return NULL;
+
+ if (XFindContext(dpy, window, wWinContext, (XPointer *) & desc) == XCNOENT)
+ return NULL;
+
+ if (desc->parent_type == WCLASS_APPICON || desc->parent_type == WCLASS_DOCK_ICON)
+ return desc->parent;
+
+ return NULL;
+}
diff --git a/src/appicon.h b/src/appicon.h
index a6c6a6a..6f72c8e 100644
--- a/src/appicon.h
+++ b/src/appicon.h
@@ -83,4 +83,5 @@ void paint_app_icon(WApplication *wapp);
void unpaint_app_icon(WApplication *wapp);
void wApplicationExtractDirPackIcon(WScreen * scr, char *path, char *wm_instance,
char *wm_class);
+WAppIcon *wAppIconFor(Window window);
#endif
diff --git a/src/xinerama.c b/src/xinerama.c
index 823df99..4bd9ca4 100644
--- a/src/xinerama.c
+++ b/src/xinerama.c
@@ -201,6 +201,25 @@ Bool wWindowTouchesHead(WWindow * wwin, int head)
return (a != 0);
}
+Bool wAppIconTouchesHead(WAppIcon * aicon, int head)
+{
+ WScreen *scr;
+ WMRect rect;
+ int a;
+
+ if (!aicon || !aicon->icon)
+ return False;
+
+ scr = aicon->icon->core->screen_ptr;
+ rect = wGetRectForHead(scr, head);
+ a = calcIntersectionArea(aicon->x_pos, aicon->y_pos,
+ aicon->icon->core->width,
+ aicon->icon->core->height,
+ rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
+
+ return (a != 0);
+}
+
int wGetHeadForWindow(WWindow * wwin)
{
WMRect rect;
diff --git a/src/xinerama.h b/src/xinerama.h
index 0699726..fd1d469 100644
--- a/src/xinerama.h
+++ b/src/xinerama.h
@@ -21,6 +21,7 @@
#ifndef _WMXINERAMA_H_
#define _WMXINERAMA_H_
+#include "appicon.h"
#include "screen.h"
#include "window.h"
#include <WINGs/WINGs.h>
@@ -51,6 +52,7 @@ WArea wGetUsableAreaForHead(WScreen *scr, int head, WArea *totalAreaPtr, Bool no
WMPoint wGetPointToCenterRectInHead(WScreen *scr, int head, int width, int height);
Bool wWindowTouchesHead(WWindow *wwin, int head);
+Bool wAppIconTouchesHead(WAppIcon *aicon, int head);
#endif
--
1.7.11.7
>From be318a0cde7bf3c13f1545743bb0671f8d66d599 Mon Sep 17 00:00:00 2001
From: Iain Patterson <[email protected]>
Date: Mon, 29 Oct 2012 15:49:43 -0700
Subject: [PATCH 2/3] Allow struts from all windows.
Respect _NET_WM_STRUT and _NET_WM_STRUT_PARTIAL from all windows, not
just WWindows. This will allow us to respect struts from app icons
and dock icons.
---
src/wmspec.c | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/src/wmspec.c b/src/wmspec.c
index 4ca8af4..6bd51ce 100644
--- a/src/wmspec.c
+++ b/src/wmspec.c
@@ -845,24 +845,21 @@ static void updateStateHint(WWindow *wwin, Bool changedWorkspace, Bool del)
}
}
-static Bool updateStrut(WWindow *wwin, Bool adding)
+static Bool updateStrut(WScreen *scr, Window w, Bool adding)
{
- WScreen *scr;
WReservedArea *area;
Bool hasState = False;
- scr = wwin->screen_ptr;
-
if (adding) {
Atom type_ret;
int fmt_ret;
unsigned long nitems_ret, bytes_after_ret;
long *data = NULL;
- if ((XGetWindowProperty(dpy, wwin->client_win, net_wm_strut, 0, 4, False,
+ if ((XGetWindowProperty(dpy, w, net_wm_strut, 0, 4, False,
XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret,
&bytes_after_ret, (unsigned char **)&data) == Success && data) ||
- ((XGetWindowProperty(dpy, wwin->client_win, net_wm_strut_partial, 0, 12, False,
+ ((XGetWindowProperty(dpy, w, net_wm_strut_partial, 0, 12, False,
XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret,
&bytes_after_ret, (unsigned char **)&data) == Success && data))) {
@@ -879,7 +876,7 @@ static Bool updateStrut(WWindow *wwin, Bool adding)
area->area.y1 = data[2];
area->area.y2 = data[3];
- area->window = wwin->client_win;
+ area->window = w;
area->next = scr->netdata->strut;
scr->netdata->strut = area;
@@ -892,12 +889,12 @@ static Bool updateStrut(WWindow *wwin, Bool adding)
area = scr->netdata->strut;
if (area) {
- if (area->window == wwin->client_win) {
+ if (area->window == w) {
scr->netdata->strut = area->next;
wfree(area);
hasState = True;
} else {
- while (area->next && area->next->window != wwin->client_win)
+ while (area->next && area->next->window != w)
area = area->next;
if (area->next) {
@@ -1234,8 +1231,8 @@ void wNETWMCheckClientHints(WWindow *wwin, int *layer, int *workspace)
}
wNETWMUpdateActions(wwin, False);
- updateStrut(wwin, False);
- updateStrut(wwin, True);
+ updateStrut(wwin->screen_ptr, wwin->client_win, False);
+ updateStrut(wwin->screen_ptr, wwin->client_win, True);
wScreenUpdateUsableArea(wwin->screen_ptr);
}
@@ -1459,8 +1456,8 @@ void wNETWMCheckClientHintChange(WWindow *wwin, XPropertyEvent *event)
#endif
if (event->atom == net_wm_strut || event->atom == net_wm_strut_partial) {
- updateStrut(wwin, False);
- updateStrut(wwin, True);
+ updateStrut(wwin->screen_ptr, wwin->client_win, False);
+ updateStrut(wwin->screen_ptr, wwin->client_win, True);
wScreenUpdateUsableArea(wwin->screen_ptr);
} else if (event->atom == net_wm_handled_icons || event->atom == net_wm_icon_geometry) {
updateNetIconInfo(wwin);
@@ -1547,8 +1544,8 @@ static void observer(void *self, WMNotification *notif)
updateClientListStacking(wwin->screen_ptr, NULL);
updateStateHint(wwin, True, False);
- updateStrut(wwin, False);
- updateStrut(wwin, True);
+ updateStrut(wwin->screen_ptr, wwin->client_win, False);
+ updateStrut(wwin->screen_ptr, wwin->client_win, True);
wScreenUpdateUsableArea(wwin->screen_ptr);
} else if (strcmp(name, WMNUnmanaged) == 0 && wwin) {
updateClientList(wwin->screen_ptr);
@@ -1557,7 +1554,7 @@ static void observer(void *self, WMNotification *notif)
updateStateHint(wwin, False, True);
wNETWMUpdateActions(wwin, True);
- updateStrut(wwin, False);
+ updateStrut(wwin->screen_ptr, wwin->client_win, False);
wScreenUpdateUsableArea(wwin->screen_ptr);
} else if (strcmp(name, WMNResetStacking) == 0 && wwin) {
updateClientListStacking(wwin->screen_ptr, NULL);
--
1.7.11.7
>From 55fa9355e6002d9a34c9fb370290c7c500d17e5f Mon Sep 17 00:00:00 2001
From: Iain Patterson <[email protected]>
Date: Mon, 29 Oct 2012 15:54:12 -0700
Subject: [PATCH 3/3] Use partial struts to reserve space for icons.
Calculate the space actually used by app icons and the dock and set
partial struts on each individual icon where appropriate. Thus the
screen area reserved by icons is no larger than the space actually
taken up by those icons. In the, contrived, case that the icons are
all moved partially offscreen, reserved space will actually shrink.
---
src/appicon.c | 3 ++
src/defaults.c | 23 +++++++--
src/dock.c | 2 +
src/screen.c | 40 +--------------
src/startup.c | 4 ++
src/wmspec.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
src/wmspec.h | 1 +
7 files changed, 183 insertions(+), 50 deletions(-)
diff --git a/src/appicon.c b/src/appicon.c
index 6be3057..5d654de 100644
--- a/src/appicon.c
+++ b/src/appicon.c
@@ -50,6 +50,7 @@
#ifdef XDND
#include "xdnd.h"
#endif
+#include "wmspec.h"
/*
* icon_file for the dock is got from the preferences file by
@@ -345,6 +346,8 @@ void wAppIconMove(WAppIcon * aicon, int x, int y)
XMoveWindow(dpy, aicon->icon->core->window, x, y);
aicon->x_pos = x;
aicon->y_pos = y;
+ wIconUpdateStruts(aicon->icon->core->screen_ptr, wPreferences.no_window_over_dock, True);
+ wIconUpdateStruts(aicon->icon->core->screen_ptr, wPreferences.no_window_over_icons, False);
}
#ifdef WS_INDICATOR
diff --git a/src/defaults.c b/src/defaults.c
index 458093c..79a5b68 100644
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -61,6 +61,7 @@
#include "dock.h"
#include "workspace.h"
#include "properties.h"
+#include "wmspec.h"
#define MAX_SHORTCUT_LENGTH 32
@@ -147,6 +148,7 @@ static int setClipTitleColor();
static int setMenuStyle();
static int setSwPOptions();
static int updateUsableArea();
+static int updateIconStruts();
static int setModifierKeyLabels();
@@ -419,9 +421,9 @@ WDefaultEntry optionList[] = {
{"AutoArrangeIcons", "NO", NULL,
&wPreferences.auto_arrange_icons, getBool, NULL, NULL, NULL},
{"NoWindowOverDock", "NO", NULL,
- &wPreferences.no_window_over_dock, getBool, updateUsableArea, NULL, NULL},
+ &wPreferences.no_window_over_dock, getBool, updateIconStruts, NULL, NULL},
{"NoWindowOverIcons", "NO", NULL,
- &wPreferences.no_window_over_icons, getBool, updateUsableArea, NULL, NULL},
+ &wPreferences.no_window_over_icons, getBool, updateIconStruts, NULL, NULL},
{"WindowPlaceOrigin", "(0, 0)", NULL,
&wPreferences.window_place_origin, getCoord, NULL, NULL, NULL},
{"ResizeDisplay", "corner", seGeomDisplays,
@@ -2818,7 +2820,8 @@ static int setKeyGrab(WScreen * scr, WDefaultEntry * entry, WShortKey * shortcut
static int setIconPosition(WScreen * scr, WDefaultEntry * entry, void *bar, void *foo)
{
- wScreenUpdateUsableArea(scr);
+ /* Disregard struts when rearranging. */
+ wIconUpdateStruts(scr, 0, 0);
wArrangeIcons(scr, True);
return 0;
@@ -2831,6 +2834,20 @@ static int updateUsableArea(WScreen * scr, WDefaultEntry * entry, void *bar, voi
return 0;
}
+static int updateIconStruts(WScreen * scr, WDefaultEntry * entry, void *value, void *foo)
+{
+ Bool do_strut = *((Bool *)value);
+ Bool only_docked = 0;
+
+ /* Same function for docked and undocked icons. */
+ if (strcmp(entry->key, "NoWindowOverDock") == 0)
+ only_docked = 1;
+
+ wIconUpdateStruts(scr, do_strut, only_docked);
+
+ return 0;
+}
+
static int setMenuStyle(WScreen * scr, WDefaultEntry * entry, int *value, void *foo)
{
return REFRESH_MENU_TEXTURE;
diff --git a/src/dock.c b/src/dock.c
index c90ae93..6ba0e76 100644
--- a/src/dock.c
+++ b/src/dock.c
@@ -54,6 +54,7 @@
#include "framewin.h"
#include "superfluous.h"
#include "xinerama.h"
+#include "wmspec.h"
/**** Local variables ****/
#define CLIP_REWIND 1
@@ -2626,6 +2627,7 @@ static void moveDock(WDock *dock, int new_x, int new_y)
XMoveWindow(dpy, btn->icon->core->window, btn->x_pos, btn->y_pos);
}
}
+ wIconUpdateStruts(dock->screen_ptr, wPreferences.no_window_over_dock, True);
}
static void swapDock(WDock *dock)
diff --git a/src/screen.c b/src/screen.c
index 2efe7c3..ffa9a8c 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -729,29 +729,18 @@ void wScreenUpdateUsableArea(WScreen * scr)
{
/*
* scr->totalUsableArea[] will become the usableArea used for Windowplacement,
- * scr->usableArea[] will be used for iconplacement, hence no iconyard nor
- * border.
+ * scr->usableArea[] will be used for iconplacement, hence no border.
*/
WArea area;
- int i, dock_head;
+ int i;
unsigned long best_area, tmp_area;
unsigned int size, position;
- dock_head = scr->xine_info.primary_head;
best_area = 0;
size = wPreferences.workspace_border_size;
position = wPreferences.workspace_border_position;
- if (scr->dock) {
- WMRect rect;
- rect.pos.x = scr->dock->x_pos;
- rect.pos.y = scr->dock->y_pos;
- rect.size.width = wPreferences.icon_size;
- rect.size.height = wPreferences.icon_size;
- dock_head = wGetHeadForRect(scr, rect);
- }
-
for (i = 0; i < wXineramaHeads(scr); ++i) {
WMRect rect = wGetRectForHead(scr, i);
scr->totalUsableArea[i].x1 = rect.pos.x;
@@ -759,16 +748,6 @@ void wScreenUpdateUsableArea(WScreen * scr)
scr->totalUsableArea[i].x2 = rect.pos.x + rect.size.width;
scr->totalUsableArea[i].y2 = rect.pos.y + rect.size.height;
- if (scr->dock && dock_head == i && (!scr->dock->lowered || wPreferences.no_window_over_dock)) {
- int offset = wPreferences.icon_size + DOCK_EXTRA_SPACE;
-
- if (scr->dock->on_right_side) {
- scr->totalUsableArea[i].x2 -= offset;
- } else {
- scr->totalUsableArea[i].x1 += offset;
- }
- }
-
if (wNETWMGetUsableArea(scr, i, &area)) {
scr->totalUsableArea[i].x1 = WMAX(scr->totalUsableArea[i].x1, area.x1);
scr->totalUsableArea[i].y1 = WMAX(scr->totalUsableArea[i].y1, area.y1);
@@ -782,21 +761,6 @@ void wScreenUpdateUsableArea(WScreen * scr)
printf("usableArea[%d]: %d %d %d %d\n", i,
scr->usableArea[i].x1, scr->usableArea[i].x2, scr->usableArea[i].y1, scr->usableArea[i].y2);
#endif
- if (wPreferences.no_window_over_icons) {
- if (wPreferences.icon_yard & IY_VERT) {
- if (wPreferences.icon_yard & IY_RIGHT) {
- scr->totalUsableArea[i].x2 -= wPreferences.icon_size;
- } else {
- scr->totalUsableArea[i].x1 += wPreferences.icon_size;
- }
- } else {
- if (wPreferences.icon_yard & IY_TOP) {
- scr->totalUsableArea[i].y1 += wPreferences.icon_size;
- } else {
- scr->totalUsableArea[i].y2 -= wPreferences.icon_size;
- }
- }
- }
if (scr->totalUsableArea[i].x2 - scr->totalUsableArea[i].x1 < rect.size.width / 2) {
scr->totalUsableArea[i].x1 = rect.pos.x;
diff --git a/src/startup.c b/src/startup.c
index ac7baa4..ebc877d 100644
--- a/src/startup.c
+++ b/src/startup.c
@@ -784,6 +784,10 @@ void StartUp(Bool defaultScreenOnly)
wWorkspaceForceChange(wScreen[j], lastDesktop);
else
wSessionRestoreLastWorkspace(wScreen[j]);
+
+ /* create struts for icons */
+ wIconUpdateStruts(wScreen[j], wPreferences.no_window_over_dock, True);
+ wIconUpdateStruts(wScreen[j], wPreferences.no_window_over_icons, False);
}
if (wScreenCount == 0) {
diff --git a/src/wmspec.c b/src/wmspec.c
index 6bd51ce..e9482ab 100644
--- a/src/wmspec.c
+++ b/src/wmspec.c
@@ -45,6 +45,7 @@
#include "client.h"
#include "appicon.h"
#include "wmspec.h"
+#include "dock.h"
#include "icon.h"
#include "stacking.h"
#include "xinerama.h"
@@ -231,6 +232,8 @@ static void updateCurrentWorkspace(WScreen *scr);
static void updateWorkspaceCount(WScreen *scr);
static void wNETWMShowingDesktop(WScreen *scr, Bool show);
+static void setIconStrut(WAppIcon *aicon, Bool do_strut, Bool vertical);
+
typedef struct NetData {
WScreen *scr;
WReservedArea *strut;
@@ -651,15 +654,17 @@ Bool wNETWMGetUsableArea(WScreen *scr, int head, WArea *area)
for (cur = scr->netdata->strut; cur; cur = cur->next) {
WWindow *wwin = wWindowFor(cur->window);
- if (wWindowTouchesHead(wwin, head)) {
- if (cur->area.x1 > area->x1)
- area->x1 = cur->area.x1;
- if (cur->area.y1 > area->y1)
- area->y1 = cur->area.y1;
- if (cur->area.x2 > area->x2)
- area->x2 = cur->area.x2;
- if (cur->area.y2 > area->y2)
- area->y2 = cur->area.y2;
+ WAppIcon *aicon = wAppIconFor(cur->window);
+ if ((wwin && wWindowTouchesHead(wwin, head)) ||
+ (aicon && wAppIconTouchesHead(aicon, head))) {
+ if (cur->area.x1 > area->x1)
+ area->x1 = cur->area.x1;
+ if (cur->area.y1 > area->y1)
+ area->y1 = cur->area.y1;
+ if (cur->area.x2 > area->x2)
+ area->x2 = cur->area.x2;
+ if (cur->area.y2 > area->y2)
+ area->y2 = cur->area.y2;
}
}
@@ -1621,3 +1626,140 @@ void wNETCleanupFrameExtents(WWindow *wwin)
{
XDeleteProperty(dpy, wwin->client_win, net_frame_extents);
}
+
+/* Create partial struts for dock and icons. */
+static void setIconStrut(WAppIcon *aicon, Bool do_strut, Bool vertical) {
+ WScreen *scr = aicon->icon->core->screen_ptr;
+ Window w = aicon->icon->core->window;
+ long strut[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ int buffer = 0;
+ XWindowAttributes attr;
+ Bool l, r, t, b;
+
+ /* It's only meaningful to apply a strut if
+ * the icon is on a screen edge.
+ */
+ l = r = t = b = False;
+ if (do_strut) {
+ XGetWindowAttributes(dpy, w, &attr);
+
+ /* If icons are set to populate on the same side of the screen
+ * as the dock, they will actually be away from the screen edge.
+ * If, additionally, the icon stack is taller than the dock or
+ * starts at the other end of the screen from the dock, we need
+ * to include the (apparently unused) dock space when accounting
+ * for the icons.
+ */
+ if (scr->dock) {
+ if (((wPreferences.icon_yard & IY_RIGHT) && scr->dock->on_right_side) ||
+ (!(wPreferences.icon_yard & IY_RIGHT) && !scr->dock->on_right_side))
+ buffer = wPreferences.icon_size;
+ }
+
+ if (attr.x <= buffer)
+ l = True;
+ if (attr.x >= scr->scr_width - attr.width - buffer)
+ r = True;
+ if (attr.y <= 0)
+ t = True;
+ if (attr.y >= scr->scr_height - attr.height)
+ b = True;
+ }
+ if (!l && !r && !t && !b) {
+ XDeleteProperty(dpy, aicon->icon->core->window, net_wm_strut_partial);
+ return;
+ }
+
+ /* The first four elements of the strut array describe the
+ * reserved space at the left, right, top and bottom of the
+ * screen. The remaining elements specify the start and
+ * end co-ordinates of the space in the other axis.
+ *
+ * So if "left" is non-zero then "left_start_y" specifies
+ * the start y co-ordinate and "left_end_y" specifies the
+ * end y co-ordinate of the left strut.
+ *
+ * Index 0 = left
+ * 1 = right
+ * 2 = top
+ * 3 = bottom
+ * 4 = left_start_y
+ * 5 = left_end_y
+ * 6 = right_start_y
+ * 7 = right_end_y
+ * 8 = top_start_x
+ * 9 = top_start_y
+ * 10 = bottom_start_x
+ * 11 = bottom_end_x
+ */
+ if (l && vertical) {
+ /* Allow the strut to start left of screen. */
+ strut[0] = attr.width + attr.x + DOCK_EXTRA_SPACE;
+ /* Don't start above the screen. */
+ if (attr.y > 0)
+ strut[4] = attr.y;
+ /* Don't end below the screen. */
+ strut[5] = attr.y + attr.height;
+ if (strut[5] > scr->scr_height)
+ strut[5] = scr->scr_height;
+ }
+ if (r && vertical) {
+ /* Allow the strut to end right of screen. */
+ strut[1] = scr->scr_width - attr.x - DOCK_EXTRA_SPACE;
+ /* Don't start above the screen. */
+ if (attr.y > 0)
+ strut[6] = attr.y;
+ /* Don't end below the screen. */
+ strut[7] = attr.y + attr.height;
+ if (strut[7] > scr->scr_height)
+ strut[7] = scr->scr_height;
+ }
+ if (t && !vertical) {
+ /* Allow the strut to start above the screen. */
+ strut[2] = attr.height + attr.y + DOCK_EXTRA_SPACE;
+ /* Don't start left of screen. */
+ if (attr.x > 0)
+ strut[8] = attr.x;
+ /* Don't end right of screen. */
+ strut[9] = attr.x + attr.width;
+ if (strut[9] > scr->scr_width)
+ strut[9] = scr->scr_width;
+ }
+ if (b && !vertical) {
+ /* Allow the strut to end below the screen. */
+ strut[3] = scr->scr_height - attr.y - DOCK_EXTRA_SPACE;
+ /* Don't start left of screen. */
+ if (attr.x > 0)
+ strut[10] = attr.x;
+ /* Don't end right of screen. */
+ strut[11] = attr.x + attr.width;
+ if (strut[11] > scr->scr_width)
+ strut[11] = scr->scr_width;
+ }
+
+ XChangeProperty(dpy, w, net_wm_strut_partial, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) strut, 12);
+}
+
+void wIconUpdateStruts(WScreen *scr, Bool do_strut, Bool only_docked)
+{
+ WAppIcon *aicon;
+ Bool vertical;
+
+ if (! scr || ! scr->app_icon_list)
+ return;
+
+ /* The dock is always vertical. Icons may not be. */
+ vertical = only_docked | (wPreferences.icon_yard & IY_VERT);
+
+ aicon = scr->app_icon_list;
+ while (aicon) {
+ /* Don't count the clip! */
+ if (aicon->icon && aicon->docked == only_docked && aicon != scr->clip_icon) {
+ setIconStrut(aicon, do_strut, vertical);
+ updateStrut(scr, aicon->icon->core->window, False);
+ updateStrut(scr, aicon->icon->core->window, True);
+ wScreenUpdateUsableArea(scr);
+ }
+ aicon = aicon->next;
+ }
+}
diff --git a/src/wmspec.h b/src/wmspec.h
index 63d1eff..4259851 100644
--- a/src/wmspec.h
+++ b/src/wmspec.h
@@ -45,4 +45,5 @@ char *wNETWMGetIconName(Window window);
char *wNETWMGetWindowName(Window window);
void wNETFrameExtents(WWindow *wwin);
void wNETCleanupFrameExtents(WWindow *wwin);
+void wIconUpdateStruts(WScreen *scr, Bool do_strut, Bool only_docked);
#endif
--
1.7.11.7