>From ccd0feecb5accf0876748cbaca1ef15280d97bd7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?"Rodolfo=20Garc=C3=ADa=20Pe=C3=B1as=20(kix)"?= <[email protected]>
Date: Mon, 8 Oct 2012 05:43:22 +0200
Subject: [PATCH 3/3] Icon creation in only one function

This patch avoid the icon creation in winspector.c and adds the
ability of creating + paiting and unpainting instead icon destroy.

Now the icon is always created by wApplicationCreate and the icon
exists while the application is runnning. If the user wants to
remove the appicon, winspector.c don't removes the icon, only
don't paint it on the screen, but the icon still is created.

Probably the most difficult part in this code is how to handle the
icons in the iconlist. We must include the icon in the iconlist when
is painted, not when is created. And must be removed when is unpainted.
We can check if the icon is in the iconlist if icon->next AND icon->prev
are null, else is included in the applist. If is included, we must not
paint it again, because the function PlaceIcon() will calculate a new
icon place in the screen including the icon!, then a hole is painted.
---
 src/appicon.c    |   57 ++++++++++++++++++++++++++++++++++++++++++++----------
 src/appicon.h    |    1 +
 src/winspector.c |    6 ++----
 3 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/src/appicon.c b/src/appicon.c
index a90e35b..f2dc957 100644
--- a/src/appicon.c
+++ b/src/appicon.c
@@ -157,6 +157,33 @@ void makeAppIconFor(WApplication *wapp)
                paint_app_icon(wapp);
 }
 
+void unpaint_app_icon(WApplication *wapp)
+{
+       WAppIcon *aicon;
+       WScreen *scr = wapp->main_window_desc->screen_ptr;
+       WDock *clip = scr->workspaces[scr->current_workspace]->clip;
+
+       if (!wapp || !wapp->app_icon)
+               return;
+
+       aicon = wapp->app_icon;
+
+       /* If the icon is docked, don't continue */
+       if (aicon->docked)
+               return;
+
+       if (!clip || !aicon->attracted || !clip->collapsed)
+               XUnmapWindow(dpy, aicon->icon->core->window);
+
+       /* We want to avoid having it on the list  because otherwise
+        * there will be a hole when the icons are arranged with
+        * wArrangeIcons() */
+       remove_from_appicon_list(scr, aicon);
+
+       if (wPreferences.auto_arrange_icons && !aicon->attracted)
+               wArrangeIcons(scr, True);
+}
+
 void paint_app_icon(WApplication *wapp)
 {
        WIcon *icon;
@@ -182,11 +209,23 @@ void paint_app_icon(WApplication *wapp)
                }
                wDockAttachIcon(clip, wapp->app_icon, x, y);
        } else {
-               PlaceIcon(scr, &x, &y, 
wGetHeadForWindow(wapp->main_window_desc));
-               wAppIconMove(wapp->app_icon, x, y);
-               wLowerFrame(icon->core);
+               /* We must know if the icon is painted in the screen,
+                * because if painted, then PlaceIcon will return the next
+                * space on the screen, and the icon will move */
+               if (wapp->app_icon->next == NULL && wapp->app_icon->prev == 
NULL) {
+                       PlaceIcon(scr, &x, &y, 
wGetHeadForWindow(wapp->main_window_desc));
+                       wAppIconMove(wapp->app_icon, x, y);
+                       wLowerFrame(icon->core);
+               }
        }
 
+       /* If we want appicon (no_appicon is not set) and the icon is not
+        * in the appicon_list, we must add it. Else, we want to avoid
+        * having it on the list */
+       if (!WFLAGP(wapp->main_window_desc, no_appicon) &&
+           wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL)
+               add_to_appicon_list(scr, wapp->app_icon);
+
        if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
                XMapWindow(dpy, icon->core->window);
 
@@ -226,18 +265,13 @@ void removeAppIconFor(WApplication * wapp)
 static WAppIcon *wAppIconCreate(WWindow *leader_win)
 {
        WAppIcon *aicon;
-       WScreen *scr = leader_win->screen_ptr;
 
        aicon = wmalloc(sizeof(WAppIcon));
        wretain(aicon);
        aicon->yindex = -1;
        aicon->xindex = -1;
-
-       /* When no_appicon is set we want to avoid having it on the list
-        * because otherwise there will be a hole when the icons are
-        * arranged with wArrangeIcons() */
-       if (!WFLAGP(leader_win, no_appicon))
-               add_to_appicon_list(scr, aicon);
+       aicon->prev = NULL;
+       aicon->next = NULL;
 
        if (leader_win->wm_class)
                aicon->wm_class = wstrdup(leader_win->wm_class);
@@ -975,4 +1009,7 @@ static void remove_from_appicon_list(WScreen *scr, 
WAppIcon *appicon)
                if (appicon->prev)
                        appicon->prev->next = appicon->next;
        }
+
+       appicon->prev = NULL;
+       appicon->next = NULL;
 }
diff --git a/src/appicon.h b/src/appicon.h
index 280843c..a6c6a6a 100644
--- a/src/appicon.h
+++ b/src/appicon.h
@@ -80,6 +80,7 @@ void makeAppIconFor(WApplication * wapp);
 void removeAppIconFor(WApplication * wapp);
 void save_appicon(WAppIcon *aicon, Bool dock);
 void paint_app_icon(WApplication *wapp);
+void unpaint_app_icon(WApplication *wapp);
 void wApplicationExtractDirPackIcon(WScreen * scr, char *path, char 
*wm_instance,
                                    char *wm_class);
 #endif
diff --git a/src/winspector.c b/src/winspector.c
index 184aec7..30b88f2 100644
--- a/src/winspector.c
+++ b/src/winspector.c
@@ -770,15 +770,13 @@ static void applySettings(WMButton *button, 
InspectorPanel *panel)
        if (wapp) {
                /* do application wide stuff */
                WSETUFLAG(wapp->main_window_desc, start_hidden, 
WMGetButtonSelected(panel->appChk[0]));
-
                WSETUFLAG(wapp->main_window_desc, no_appicon, 
WMGetButtonSelected(panel->appChk[1]));
-
                WSETUFLAG(wapp->main_window_desc, shared_appicon, 
WMGetButtonSelected(panel->appChk[2]));
 
                if (WFLAGP(wapp->main_window_desc, no_appicon))
-                       removeAppIconFor(wapp);
+                       unpaint_app_icon(wapp);
                else
-                       makeAppIconFor(wapp);
+                       paint_app_icon(wapp);
 
                if (wapp->app_icon && wapp->main_window == wwin->client_win) {
                        char *file = WMGetTextFieldText(panel->fileText);
-- 
1.7.10.4

-- 
||// //\\// Rodolfo "kix" Garcia
||\\// //\\ http://www.kix.es/
>From ccd0feecb5accf0876748cbaca1ef15280d97bd7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?"Rodolfo=20Garc=C3=ADa=20Pe=C3=B1as=20(kix)"?= <[email protected]>
Date: Mon, 8 Oct 2012 05:43:22 +0200
Subject: [PATCH 3/3] Icon creation in only one function

This patch avoid the icon creation in winspector.c and adds the
ability of creating + paiting and unpainting instead icon destroy.

Now the icon is always created by wApplicationCreate and the icon
exists while the application is runnning. If the user wants to
remove the appicon, winspector.c don't removes the icon, only
don't paint it on the screen, but the icon still is created.

Probably the most difficult part in this code is how to handle the
icons in the iconlist. We must include the icon in the iconlist when
is painted, not when is created. And must be removed when is unpainted.
We can check if the icon is in the iconlist if icon->next AND icon->prev
are null, else is included in the applist. If is included, we must not
paint it again, because the function PlaceIcon() will calculate a new
icon place in the screen including the icon!, then a hole is painted.
---
 src/appicon.c    |   57 ++++++++++++++++++++++++++++++++++++++++++++----------
 src/appicon.h    |    1 +
 src/winspector.c |    6 ++----
 3 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/src/appicon.c b/src/appicon.c
index a90e35b..f2dc957 100644
--- a/src/appicon.c
+++ b/src/appicon.c
@@ -157,6 +157,33 @@ void makeAppIconFor(WApplication *wapp)
 		paint_app_icon(wapp);
 }
 
+void unpaint_app_icon(WApplication *wapp)
+{
+	WAppIcon *aicon;
+	WScreen *scr = wapp->main_window_desc->screen_ptr;
+	WDock *clip = scr->workspaces[scr->current_workspace]->clip;
+
+	if (!wapp || !wapp->app_icon)
+		return;
+
+	aicon = wapp->app_icon;
+
+	/* If the icon is docked, don't continue */
+	if (aicon->docked)
+		return;
+
+	if (!clip || !aicon->attracted || !clip->collapsed)
+		XUnmapWindow(dpy, aicon->icon->core->window);
+
+	/* We want to avoid having it on the list  because otherwise
+	 * there will be a hole when the icons are arranged with
+	 * wArrangeIcons() */
+	remove_from_appicon_list(scr, aicon);
+
+	if (wPreferences.auto_arrange_icons && !aicon->attracted)
+		wArrangeIcons(scr, True);
+}
+
 void paint_app_icon(WApplication *wapp)
 {
 	WIcon *icon;
@@ -182,11 +209,23 @@ void paint_app_icon(WApplication *wapp)
 		}
 		wDockAttachIcon(clip, wapp->app_icon, x, y);
 	} else {
-		PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc));
-		wAppIconMove(wapp->app_icon, x, y);
-		wLowerFrame(icon->core);
+		/* We must know if the icon is painted in the screen,
+		 * because if painted, then PlaceIcon will return the next
+		 * space on the screen, and the icon will move */
+		if (wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL) {
+			PlaceIcon(scr, &x, &y, wGetHeadForWindow(wapp->main_window_desc));
+			wAppIconMove(wapp->app_icon, x, y);
+			wLowerFrame(icon->core);
+		}
 	}
 
+	/* If we want appicon (no_appicon is not set) and the icon is not
+	 * in the appicon_list, we must add it. Else, we want to avoid
+	 * having it on the list */
+	if (!WFLAGP(wapp->main_window_desc, no_appicon) &&
+	    wapp->app_icon->next == NULL && wapp->app_icon->prev == NULL)
+		add_to_appicon_list(scr, wapp->app_icon);
+
 	if (!clip || !wapp->app_icon->attracted || !clip->collapsed)
 		XMapWindow(dpy, icon->core->window);
 
@@ -226,18 +265,13 @@ void removeAppIconFor(WApplication * wapp)
 static WAppIcon *wAppIconCreate(WWindow *leader_win)
 {
 	WAppIcon *aicon;
-	WScreen *scr = leader_win->screen_ptr;
 
 	aicon = wmalloc(sizeof(WAppIcon));
 	wretain(aicon);
 	aicon->yindex = -1;
 	aicon->xindex = -1;
-
-	/* When no_appicon is set we want to avoid having it on the list
-	 * because otherwise there will be a hole when the icons are
-	 * arranged with wArrangeIcons() */
-	if (!WFLAGP(leader_win, no_appicon))
-		add_to_appicon_list(scr, aicon);
+	aicon->prev = NULL;
+	aicon->next = NULL;
 
 	if (leader_win->wm_class)
 		aicon->wm_class = wstrdup(leader_win->wm_class);
@@ -975,4 +1009,7 @@ static void remove_from_appicon_list(WScreen *scr, WAppIcon *appicon)
 		if (appicon->prev)
 			appicon->prev->next = appicon->next;
 	}
+
+	appicon->prev = NULL;
+	appicon->next = NULL;
 }
diff --git a/src/appicon.h b/src/appicon.h
index 280843c..a6c6a6a 100644
--- a/src/appicon.h
+++ b/src/appicon.h
@@ -80,6 +80,7 @@ void makeAppIconFor(WApplication * wapp);
 void removeAppIconFor(WApplication * wapp);
 void save_appicon(WAppIcon *aicon, Bool dock);
 void paint_app_icon(WApplication *wapp);
+void unpaint_app_icon(WApplication *wapp);
 void wApplicationExtractDirPackIcon(WScreen * scr, char *path, char *wm_instance,
 				    char *wm_class);
 #endif
diff --git a/src/winspector.c b/src/winspector.c
index 184aec7..30b88f2 100644
--- a/src/winspector.c
+++ b/src/winspector.c
@@ -770,15 +770,13 @@ static void applySettings(WMButton *button, InspectorPanel *panel)
 	if (wapp) {
 		/* do application wide stuff */
 		WSETUFLAG(wapp->main_window_desc, start_hidden, WMGetButtonSelected(panel->appChk[0]));
-
 		WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1]));
-
 		WSETUFLAG(wapp->main_window_desc, shared_appicon, WMGetButtonSelected(panel->appChk[2]));
 
 		if (WFLAGP(wapp->main_window_desc, no_appicon))
-			removeAppIconFor(wapp);
+			unpaint_app_icon(wapp);
 		else
-			makeAppIconFor(wapp);
+			paint_app_icon(wapp);
 
 		if (wapp->app_icon && wapp->main_window == wwin->client_win) {
 			char *file = WMGetTextFieldText(panel->fileText);
-- 
1.7.10.4

Reply via email to