Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37498732
en ru br
Репозитории ALT
S:0.96.0-alt1
5.1: 0.92.0-alt6
4.1: 0.92.0-alt2
4.0: 0.92.0-alt2
3.0: 0.91.0-alt1
+backports:0.92.0-alt0.M30.1
www.altlinux.org/Changes

Группа :: Графические оболочки/Window Maker
Пакет: WindowMaker

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: WindowMaker-0.92.0-peter-appicon-bouncer2.patch
Скачать


 src/application.c |   10 +++
 src/application.h |    5 ++
 src/superfluous.c |  162 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/window.c      |    1 +
 4 files changed, 178 insertions(+), 0 deletions(-)
diff --git a/src/application.c b/src/application.c
index 5676f25..9514a46 100644
--- a/src/application.c
+++ b/src/application.c
@@ -448,6 +448,16 @@ wApplicationDestroy(WApplication *wapp)
     if (wapp->refcount>0)
         return;
 
+#ifdef BOUNCE_APP
+    if (wapp->flags.bouncing)
+    {
+	/* event.c:handleDestroyNotify forced this destroy
+	   and thereby overlooked the bounce callback */
+	wapp->refcount = 1;
+	return;
+    }
+#endif
+
 
     scr = wapp->main_window_desc->screen_ptr;
     main_window = wapp->main_window;
diff --git a/src/application.h b/src/application.h
index c0165ce..961e1e5 100644
--- a/src/application.h
+++ b/src/application.h
@@ -46,6 +46,9 @@ typedef struct WApplication {
         unsigned int skip_next_animation:1;
         unsigned int hidden:1;
         unsigned int emulated:1;
+#ifdef BOUNCE_APP
+	unsigned int bouncing:1;
+#endif
     } flags;
 } WApplication;
 
@@ -58,6 +61,8 @@ WApplication *wApplicationOf(Window window);
 void wApplicationExtractDirPackIcon(WScreen *scr,char *path, char *wm_instance,
                                     char *wm_class);
 
+void wAppBounce(WApplication *);
+
 #ifdef NEWAPPICON
 
 #define wApplicationActivate(wapp) do { \
diff --git a/src/superfluous.c b/src/superfluous.c
index 8699d81..e9ab2fc 100644
--- a/src/superfluous.c
+++ b/src/superfluous.c
@@ -41,6 +41,7 @@
 #include "window.h"
 #include "icon.h"
 #include "appicon.h"
+#include "xinerama.h"
 
 
 extern WPreferences wPreferences;
@@ -811,3 +812,164 @@ UpdateGhostWindowMove(void *data, int x, int y)
 
 #endif /* GHOST_WINDOW_MOVE */
 
+#ifdef BOUNCE_APP
+
+#define BOUNCE_HZ	25
+#define BOUNCE_DELAY	(1000/BOUNCE_HZ)
+#define BOUNCE_HEIGHT	24
+#define BOUNCE_LENGTH	0.3
+#define BOUNCE_DAMP	0.6
+
+typedef struct AppBouncerData {
+    WApplication *wapp;
+    int count;
+    int pow;
+    int dir;
+    WMHandlerID *timer;
+} AppBouncerData;
+
+static void 
+doAppBounce(void *arg)
+{
+    AppBouncerData *data = (AppBouncerData*)arg;
+    WAppIcon *aicon = data->wapp->app_icon;
+
+reinit:
+    if (aicon && data->wapp->refcount > 1)
+    {
+	const double ticks = BOUNCE_HZ*BOUNCE_LENGTH;
+	const double s = sqrt(BOUNCE_HEIGHT)/(ticks/2);
+	double h = BOUNCE_HEIGHT*pow(BOUNCE_DAMP, data->pow);
+	double sqrt_h = sqrt(h);
+	if (h > 3)
+	{
+	    double offset, x = s * data->count - sqrt_h;
+	    if (x > sqrt_h)
+	    {
+		++data->pow;
+		data->count = 0;
+		goto reinit;
+	    } else ++data->count;
+	    offset = h - x*x;
+	    
+	    switch(data->dir)
+	    {
+		case 0: /* left, bounce to right */
+		    XMoveWindow(dpy, aicon->icon->core->window, 
+				aicon->x_pos + (int)offset, aicon->y_pos);
+		    break;
+		case 1: /* right, bounce to left */
+		    XMoveWindow(dpy, aicon->icon->core->window, 
+				aicon->x_pos - (int)offset, aicon->y_pos);
+		    break;
+		case 2: /* top, bounce down */
+		    XMoveWindow(dpy, aicon->icon->core->window, 
+				aicon->x_pos, aicon->y_pos + (int)offset);
+		    break;
+		case 3: /* bottom, bounce up */
+		    XMoveWindow(dpy, aicon->icon->core->window, 
+				aicon->x_pos, aicon->y_pos - (int)offset);
+		    break;
+	    }
+	    return;
+	}
+	XMoveWindow(dpy, aicon->icon->core->window, 
+		    aicon->x_pos, aicon->y_pos);
+    }
+
+    data->wapp->flags.bouncing = 0;
+    WMDeleteTimerHandler(data->timer);
+    wApplicationDestroy(data->wapp);
+    free(data);
+}
+
+static int
+bounceDirection(WAppIcon *aicon)
+{
+    enum { left_e = 1, right_e = 2, top_e = 4, bottom_e = 8 };
+
+    WScreen *scr = aicon->icon->core->screen_ptr;
+    WMRect rr, sr;
+    int l,r,t,b, h,v;
+    int dir = 0;
+
+    rr.pos.x = aicon->x_pos;
+    rr.pos.y = aicon->y_pos;
+    rr.size.width = rr.size.height = 64;
+    
+    sr = wGetRectForHead(scr, wGetHeadForRect(scr, rr));
+
+    l = rr.pos.x - sr.pos.x;
+    r = sr.pos.x + sr.size.width - rr.pos.x - rr.size.width;
+    t = rr.pos.y - sr.pos.y;
+    b = sr.pos.y + sr.size.height - rr.pos.y - rr.size.height;
+
+    if (l < r) {
+	dir |= left_e;
+	h = l;
+    } else {
+	dir |= right_e;
+	h = r;
+    }
+
+    if (t < b) {
+	dir |= top_e;
+	v = t;
+    } else {
+	dir |= bottom_e;
+	v = b;
+    }
+
+    if (h < v) dir &= ~(top_e | bottom_e);
+    else dir &= ~(left_e | right_e);
+
+    switch(dir)
+    {
+	case left_e:
+	    dir = 0;
+	    break;
+
+	case right_e:
+	    dir = 1;
+	    break;
+
+	case top_e:
+	    dir = 2;
+	    break;
+
+	case bottom_e:
+	    dir = 3;
+	    break;
+
+	default:
+	    wwarning(_("impossible direction: %d\n"), dir);
+	    dir = 3;
+	    break;
+    }
+
+    return dir;
+}
+
+void 
+wAppBounce(WApplication * wapp)
+{
+    if (wapp->app_icon && !wapp->flags.bouncing)
+    {
+	++wapp->refcount;
+	wapp->flags.bouncing = 1;
+
+	AppBouncerData *data = 
+	    (AppBouncerData*)malloc(sizeof(AppBouncerData));
+	data->wapp = wapp;
+	data->count = data->pow = 0;
+	data->dir = bounceDirection(wapp->app_icon);
+	data->timer = WMAddPersistentTimerHandler(BOUNCE_DELAY, doAppBounce, data);
+    }
+}
+
+#else
+void
+wAppBounce(WApplication * wapp)
+{
+}
+#endif
diff --git a/src/window.c b/src/window.c
index 4c0a8fc..372a110 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1399,6 +1399,7 @@ wManageWindow(WScreen *scr, Window window)
                     raise = True;
                 }
             }
+	    wAppBounce(app);
         }
     }
 
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin