From ece6d213aa52d1014f73b647737c46ce274f0c7b Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Fri, 17 Sep 2010 15:33:13 -0400 Subject: [PATCH] Option to raise bouncing appicons 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 --- 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 263af90e..f8a819fc 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 9aaacb57..5b4245bf 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 9183382f..9333e3be 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 8199c8d7..fb4033c5 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 73245b61..2d0b36db 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 6271851e..b2415024 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); -- 2.11.4.GIT