If the appicon is not in the dock/clip, or the dock/clip is not set to
"Keep on Top", there's a good chance you won't actually see the bouncing
because some other window is covering the appicon.

Besides adding the option to raise bouncing windows, this patch adds a
utility method to move a window back into its correct stacking position
after it has been messed with using XRaiseWindow.

Signed-off-by: Brad Jorsch <[email protected]>
---
 WPrefs.app/Expert.c |    7 +++++--
 src/WindowMaker.h   |    1 +
 src/defaults.c      |    2 ++
 src/stacking.c      |   40 ++++++++++++++++++++++++++++++++++++++++
 src/stacking.h      |    2 ++
 src/superfluous.c   |    4 ++++
 6 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/WPrefs.app/Expert.c b/WPrefs.app/Expert.c
index 263af90..f8a819f 100644
--- a/WPrefs.app/Expert.c
+++ b/WPrefs.app/Expert.c
@@ -32,7 +32,7 @@ typedef struct _Panel {
 
        WMWidget *parent;
 
-       WMButton *swi[11];
+       WMButton *swi[12];
 
 } _Panel;
 
@@ -53,6 +53,7 @@ static void showData(_Panel * panel)
        WMSetButtonSelected(panel->swi[8], 
GetBoolForKey("CycleActiveHeadOnly"));
        WMSetButtonSelected(panel->swi[9], GetBoolForKey("ShowClipTitle"));
        WMSetButtonSelected(panel->swi[10], 
GetBoolForKey("BounceAppIconsWhenUrgent"));
+       WMSetButtonSelected(panel->swi[11], 
GetBoolForKey("RaiseAppIconsWhenBouncing"));
 }
 
 static void createPanel(Panel * p)
@@ -94,8 +95,9 @@ static void createPanel(Panel * p)
        WMSetButtonText(panel->swi[8], _("Cycle windows only on the active 
head."));
        WMSetButtonText(panel->swi[9], _("Show workspace title on Clip."));
        WMSetButtonText(panel->swi[10], _("Bounce AppIcons when the application 
wants attention."));
+       WMSetButtonText(panel->swi[11], _("Raise AppIcons when bouncing."));
 
-        /* If the item is default true, enable the button here */
+       /* If the item is default true, enable the button here */
        WMSetButtonEnabled(panel->swi[6], True);
        WMSetButtonEnabled(panel->swi[9], True);
        WMSetButtonEnabled(panel->swi[10], True);
@@ -124,6 +126,7 @@ static void storeDefaults(_Panel * panel)
        SetBoolForKey(WMGetButtonSelected(panel->swi[8]), 
"CycleActiveHeadOnly");
        SetBoolForKey(WMGetButtonSelected(panel->swi[9]), "ShowClipTitle");
        SetBoolForKey(WMGetButtonSelected(panel->swi[10]), 
"BounceAppIconsWhenUrgent");
+       SetBoolForKey(WMGetButtonSelected(panel->swi[11]), 
"RaiseAppIconsWhenBouncing");
 }
 
 Panel *InitExpert(WMScreen * scr, WMWidget * parent)
diff --git a/src/WindowMaker.h b/src/WindowMaker.h
index 9aaacb5..5b4245b 100644
--- a/src/WindowMaker.h
+++ b/src/WindowMaker.h
@@ -411,6 +411,7 @@ typedef struct WPreferences {
 
     /* bouncing animation */
     char bounce_appicons_when_urgent;
+    char raise_appicons_when_bouncing;
 
     int edge_resistance;
     int resize_increment;
diff --git a/src/defaults.c b/src/defaults.c
index 9183382..9333e3b 100644
--- a/src/defaults.c
+++ b/src/defaults.c
@@ -382,6 +382,8 @@ WDefaultEntry optionList[] = {
            &wPreferences.shade_speed, getEnum, NULL, NULL, NULL},
        {"BounceAppIconsWhenUrgent", "YES", NULL,
            &wPreferences.bounce_appicons_when_urgent, getBool, NULL, NULL, 
NULL},
+       {"RaiseAppIconsWhenBouncing", "NO", NULL,
+           &wPreferences.raise_appicons_when_bouncing, getBool, NULL, NULL, 
NULL},
        {"DoubleClickTime", "250", (void *)&wPreferences.dblclick_time,
            &wPreferences.dblclick_time, getInt, setDoubleClick, NULL, NULL},
        {"AlignSubmenus", "NO", NULL,
diff --git a/src/stacking.c b/src/stacking.c
index 8199c8d..fb4033c 100644
--- a/src/stacking.c
+++ b/src/stacking.c
@@ -159,6 +159,46 @@ static void moveFrameToUnder(WCoreWindow * under, 
WCoreWindow * frame)
 
 /*
  *----------------------------------------------------------------------
+ * CommitStackingForWindow--
+ *     Reorders the stacking for the specified window, so that it has the
+ * stacking order in the internal window stacking lists.
+ *
+ * Side effects:
+ *     Windows may be restacked.
+ *----------------------------------------------------------------------
+ */
+void CommitStackingForWindow(WCoreWindow * frame)
+{
+       int level = frame->stacking->window_level;
+       WScreen *scr = frame->screen_ptr;
+
+       if (frame->stacking->above == NULL) {
+               WMBagIterator iter;
+               WCoreWindow *above = WMBagLast(scr->stacking_list, &iter);
+               int i, last = above->stacking->window_level;
+
+               /* find the 1st level above us which has windows in it */
+               for (i = level + 1, above = NULL; i <= last; i++) {
+                       above = WMGetFromBag(scr->stacking_list, i);
+                       if (above != NULL)
+                               break;
+               }
+
+               if (above != frame && above != NULL) {
+                       while (above->stacking->under)
+                               above = above->stacking->under;
+                       moveFrameToUnder(above, frame);
+               } else {
+                       /* no window above us */
+                       XRaiseWindow(dpy, frame->window);
+               }
+       } else {
+               moveFrameToUnder(frame->stacking->above, frame);
+       }
+}
+
+/*
+ *----------------------------------------------------------------------
  * wRaiseFrame--
  *     Raises a frame taking the window level into account.
  *
diff --git a/src/stacking.h b/src/stacking.h
index 73245b6..2d0b36d 100644
--- a/src/stacking.h
+++ b/src/stacking.h
@@ -42,4 +42,6 @@ void RemakeStackList(WScreen *scr);
 
 void CommitStacking(WScreen *scr);
 
+void CommitStackingForFrame(WCoreWindow *frame);
+
 #endif
diff --git a/src/superfluous.c b/src/superfluous.c
index 6271851..b241502 100644
--- a/src/superfluous.c
+++ b/src/superfluous.c
@@ -275,6 +275,9 @@ static void doAppBounce(void *arg)
 
 reinit:
        if (aicon && data->wapp->refcount > 1) {
+               if (wPreferences.raise_appicons_when_bouncing)
+                       XRaiseWindow(dpy, aicon->icon->core->window);
+
                const double ticks = BOUNCE_HZ * BOUNCE_LENGTH;
                const double s = sqrt(BOUNCE_HEIGHT)/(ticks/2);
                double h = BOUNCE_HEIGHT*pow(BOUNCE_DAMP, data->pow);
@@ -312,6 +315,7 @@ reinit:
                            aicon->x_pos, aicon->y_pos);
        }
 
+       CommitStackingForWindow(aicon->icon->core);
        data->wapp->flags.bouncing = 0;
        WMDeleteTimerHandler(data->timer);
        wApplicationDestroy(data->wapp);
-- 
1.7.1


-- 
To unsubscribe, send mail to [email protected].

Reply via email to