1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail    : see the 'copyright' file.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "cairo-dock-icon-facility.h"
21 #include "cairo-dock-applications-manager.h"
22 #include "cairo-dock-launcher-manager.h"  // gldi_launcher_add_new
23 #include "cairo-dock-utils.h"  // cairo_dock_launch_command_full
24 #include "cairo-dock-stack-icon-manager.h"
25 #include "cairo-dock-separator-manager.h"
26 #include "cairo-dock-applet-manager.h"
27 #include "cairo-dock-class-icon-manager.h"
28 #include "cairo-dock-dock-facility.h"
29 #include "cairo-dock-dialog-factory.h"  // gldi_dialog_show_temporary_with_default_icon
30 #include "cairo-dock-themes-manager.h"  // cairo_dock_update_conf_file
31 #include "cairo-dock-file-manager.h"  // cairo_dock_copy_file
32 #include "cairo-dock-log.h"
33 #include "cairo-dock-dock-manager.h"
34 #include "cairo-dock-keybinder.h"  // cairo_dock_trigger_shortkey
35 #include "cairo-dock-animations.h"  // gldi_icon_request_animation
36 #include "cairo-dock-class-manager.h"
37 #include "cairo-dock-desktop-manager.h"
38 #include "cairo-dock-windows-manager.h"
39 #include "cairo-dock-gui-backend.h"
40 #include "cairo-dock-user-interaction.h"
41 
42 extern gboolean g_bLocked;
43 extern gchar *g_cConfFile;
44 extern gchar *g_cCurrentIconsPath;
45 
_compare_zorder(Icon * icon1,Icon * icon2)46 static int _compare_zorder (Icon *icon1, Icon *icon2)  // classe par z-order decroissant.
47 {
48 	if (icon1->pAppli->iStackOrder < icon2->pAppli->iStackOrder)
49 		return -1;
50 	else if (icon1->pAppli->iStackOrder > icon2->pAppli->iStackOrder)
51 		return 1;
52 	else
53 		return 0;
54 }
_cairo_dock_hide_show_in_class_subdock(Icon * icon)55 static void _cairo_dock_hide_show_in_class_subdock (Icon *icon)
56 {
57 	if (icon->pSubDock == NULL || icon->pSubDock->icons == NULL)
58 		return;
59 	// if the appli has the focus, we hide all the windows, else we show them all
60 	Icon *pIcon;
61 	GList *ic;
62 	for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
63 	{
64 		pIcon = ic->data;
65 		if (pIcon->pAppli != NULL && pIcon->pAppli == gldi_windows_get_active ())
66 		{
67 			break;
68 		}
69 	}
70 
71 	if (ic != NULL)  // one of the windows of the appli has the focus -> hide.
72 	{
73 		for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
74 		{
75 			pIcon = ic->data;
76 			if (pIcon->pAppli != NULL && ! pIcon->pAppli->bIsHidden)
77 			{
78 				gldi_window_minimize (pIcon->pAppli);
79 			}
80 		}
81 	}
82 	else  // on montre tout, dans l'ordre du z-order.
83 	{
84 		GList *pZOrderList = NULL;
85 		for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
86 		{
87 			pIcon = ic->data;
88 			if (pIcon->pAppli != NULL)
89 				pZOrderList = g_list_insert_sorted (pZOrderList, pIcon, (GCompareFunc) _compare_zorder);
90 		}
91 
92 		int iNumDesktop, iViewPortX, iViewPortY;
93 		gldi_desktop_get_current (&iNumDesktop, &iViewPortX, &iViewPortY);
94 
95 		for (ic = pZOrderList; ic != NULL; ic = ic->next)
96 		{
97 			pIcon = ic->data;
98 			if (gldi_window_is_on_desktop (pIcon->pAppli, iNumDesktop, iViewPortX, iViewPortY))
99 				break;
100 		}
101 		if (pZOrderList && ic == NULL)  // no window on the current desktop -> take the first desktop
102 		{
103 			pIcon = pZOrderList->data;
104 			iNumDesktop = pIcon->pAppli->iNumDesktop;
105 			iViewPortX = pIcon->pAppli->iViewPortX;
106 			iViewPortY = pIcon->pAppli->iViewPortY;
107 		}
108 
109 		for (ic = pZOrderList; ic != NULL; ic = ic->next)
110 		{
111 			pIcon = ic->data;
112 			if (gldi_window_is_on_desktop (pIcon->pAppli, iNumDesktop, iViewPortX, iViewPortY))
113 				gldi_window_show (pIcon->pAppli);
114 		}
115 		g_list_free (pZOrderList);
116 	}
117 }
118 
_cairo_dock_show_prev_next_in_subdock(Icon * icon,gboolean bNext)119 static void _cairo_dock_show_prev_next_in_subdock (Icon *icon, gboolean bNext)
120 {
121 	if (icon->pSubDock == NULL || icon->pSubDock->icons == NULL)
122 		return;
123 	GldiWindowActor *pActiveAppli = gldi_windows_get_active ();
124 	GList *ic;
125 	Icon *pIcon;
126 	for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
127 	{
128 		pIcon = ic->data;
129 		if (pIcon->pAppli == pActiveAppli)
130 			break;
131 	}
132 	if (ic == NULL)
133 		ic = icon->pSubDock->icons;
134 
135 	GList *ic2 = ic;
136 	do
137 	{
138 		ic2 = (bNext ? cairo_dock_get_next_element (ic2, icon->pSubDock->icons) : cairo_dock_get_previous_element (ic2, icon->pSubDock->icons));
139 		pIcon = ic2->data;
140 		if (CAIRO_DOCK_IS_APPLI (pIcon))
141 		{
142 			gldi_window_show (pIcon->pAppli);
143 			break;
144 		}
145 	} while (ic2 != ic);
146 }
147 
_cairo_dock_close_all_in_class_subdock(Icon * icon)148 static void _cairo_dock_close_all_in_class_subdock (Icon *icon)
149 {
150 	if (icon->pSubDock == NULL || icon->pSubDock->icons == NULL)
151 		return;
152 	Icon *pIcon;
153 	GList *ic;
154 	for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
155 	{
156 		pIcon = ic->data;
157 		if (pIcon->pAppli != NULL)
158 		{
159 			gldi_window_close (pIcon->pAppli);
160 		}
161 	}
162 }
163 
_show_all_windows(GList * pIcons)164 static void _show_all_windows (GList *pIcons)
165 {
166 	Icon *pIcon;
167 	GList *ic;
168 	for (ic = pIcons; ic != NULL; ic = ic->next)
169 	{
170 		pIcon = ic->data;
171 		if (pIcon->pAppli != NULL && pIcon->pAppli->bIsHidden)  // a window is hidden...
172 		{
173 			gldi_window_show (pIcon->pAppli);
174 		}
175 	}
176 }
177 
178 
_launch_icon_command(Icon * icon)179 static gboolean _launch_icon_command (Icon *icon)
180 {
181 	if (icon->cCommand == NULL)
182 		return GLDI_NOTIFICATION_LET_PASS;
183 
184 	gboolean bSuccess = FALSE;
185 	if (*icon->cCommand == '<')  // shortkey
186 	{
187 		bSuccess = cairo_dock_trigger_shortkey (icon->cCommand);
188 		if (!bSuccess)
189 			bSuccess = gldi_icon_launch_command (icon);
190 	}
191 	else  // normal command
192 	{
193 		bSuccess = gldi_icon_launch_command (icon);
194 		if (! bSuccess)
195 			bSuccess = cairo_dock_trigger_shortkey (icon->cCommand);
196 	}
197 	if (! bSuccess)
198 	{
199 		gldi_icon_request_animation (icon, "blink", 1);  // 1 blink if fail.
200 	}
201 	return GLDI_NOTIFICATION_INTERCEPT;
202 }
cairo_dock_notification_click_icon(G_GNUC_UNUSED gpointer pUserData,Icon * icon,GldiContainer * pContainer,guint iButtonState)203 gboolean cairo_dock_notification_click_icon (G_GNUC_UNUSED gpointer pUserData, Icon *icon, GldiContainer *pContainer, guint iButtonState)
204 {
205 	if (icon == NULL || ! CAIRO_DOCK_IS_DOCK (pContainer))
206 		return GLDI_NOTIFICATION_LET_PASS;
207 	CairoDock *pDock = CAIRO_DOCK (pContainer);
208 
209 	// shit/ctrl + click on an icon that is linked to a program => re-launch this program.
210 	if (iButtonState & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))  // shit or ctrl + click
211 	{
212 		if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon)
213 		|| CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon)
214 		|| CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (icon))
215 		{
216 			_launch_icon_command (icon);
217 		}
218 		return GLDI_NOTIFICATION_LET_PASS;
219 	}
220 
221 	// scale on an icon holding a class sub-dock.
222 	if (CAIRO_DOCK_IS_MULTI_APPLI(icon))
223 	{
224 		if (myTaskbarParam.bPresentClassOnClick // if we want to use this feature
225 		&& (!myDocksParam.bShowSubDockOnClick  // if sub-docks are shown on mouse over
226 			|| gldi_container_is_visible (CAIRO_CONTAINER (icon->pSubDock)))  // or this sub-dock is already visible
227 		&& gldi_desktop_present_class (icon->cClass)) // we use the scale plugin if it's possible
228 		{
229 			_show_all_windows (icon->pSubDock->icons); // show all windows
230 			// in case the dock is visible or about to be visible, hide it, as it would confuse the user to have both.
231 			cairo_dock_emit_leave_signal (CAIRO_CONTAINER (icon->pSubDock));
232 			return GLDI_NOTIFICATION_INTERCEPT;
233 		}
234 	}
235 
236 	// else handle sub-docks showing on click, applis and launchers (not applets).
237 	if (icon->pSubDock != NULL && (myDocksParam.bShowSubDockOnClick || !gldi_container_is_visible (CAIRO_CONTAINER (icon->pSubDock))))  // icon pointing to a sub-dock with either "sub-dock activation on click" option enabled, or sub-dock not visible -> open the sub-dock
238 	{
239 		cairo_dock_show_subdock (icon, pDock);
240 		return GLDI_NOTIFICATION_INTERCEPT;
241 	}
242 	else if (CAIRO_DOCK_IS_APPLI (icon) && ! CAIRO_DOCK_IS_APPLET (icon))  // icon holding an appli, but not being an applet -> show/hide the window.
243 	{
244 		GldiWindowActor *pAppli = icon->pAppli;
245 		if (gldi_windows_get_active () == pAppli && myTaskbarParam.bMinimizeOnClick && ! pAppli->bIsHidden && gldi_window_is_on_current_desktop (pAppli))  // ne marche que si le dock est une fenêtre de type 'dock', sinon il prend le focus.
246 			gldi_window_minimize (pAppli);
247 		else
248 			gldi_window_show (pAppli);
249 		return GLDI_NOTIFICATION_INTERCEPT;
250 	}
251 	else if (CAIRO_DOCK_IS_MULTI_APPLI (icon))  // icon holding a class sub-dock -> show/hide the windows of the class.
252 	{
253 		if (! myDocksParam.bShowSubDockOnClick)
254 		{
255 			_cairo_dock_hide_show_in_class_subdock (icon);
256 		}
257 		return GLDI_NOTIFICATION_INTERCEPT;
258 	}
259 	else if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon))  // finally, launcher being none of the previous cases -> launch the command
260 	{
261 		if (! gldi_class_is_starting (icon->cClass) && ! gldi_icon_is_launching (icon))  // do not launch it twice (avoid wrong double click) => if we want to launch it 2 times in a row, we have to use Shift + Click
262 			_launch_icon_command (icon);
263 	}
264 	else  // for applets and their sub-icons, let the module-instance handles the click; for separators, no action.
265 	{
266 		cd_debug ("no action here");
267 	}
268 	return GLDI_NOTIFICATION_LET_PASS;
269 }
270 
271 
cairo_dock_notification_middle_click_icon(G_GNUC_UNUSED gpointer pUserData,Icon * icon,GldiContainer * pContainer)272 gboolean cairo_dock_notification_middle_click_icon (G_GNUC_UNUSED gpointer pUserData, Icon *icon, GldiContainer *pContainer)
273 {
274 	if (icon == NULL || ! CAIRO_DOCK_IS_DOCK (pContainer))
275 		return GLDI_NOTIFICATION_LET_PASS;
276 	CairoDock *pDock = CAIRO_DOCK (pContainer);
277 
278 	if (CAIRO_DOCK_IS_APPLI (icon) && ! CAIRO_DOCK_IS_APPLET (icon) && myTaskbarParam.iActionOnMiddleClick != 0)
279 	{
280 		switch (myTaskbarParam.iActionOnMiddleClick)
281 		{
282 			case 1:  // close
283 				gldi_window_close (icon->pAppli);
284 			break;
285 			case 2:  // minimise
286 				if (! icon->pAppli->bIsHidden)
287 				{
288 					gldi_window_minimize (icon->pAppli);
289 				}
290 			break;
291 			case 3:  // launch new
292 				if (icon->cCommand != NULL)
293 				{
294 					gldi_object_notify (pDock, NOTIFICATION_CLICK_ICON, icon, pDock, GDK_SHIFT_MASK);  // on emule un shift+clic gauche .
295 				}
296 			break;
297 		}
298 		return GLDI_NOTIFICATION_INTERCEPT;
299 	}
300 	else if (CAIRO_DOCK_IS_MULTI_APPLI (icon) && myTaskbarParam.iActionOnMiddleClick != 0)
301 	{
302 		switch (myTaskbarParam.iActionOnMiddleClick)
303 		{
304 			case 1:  // close
305 				_cairo_dock_close_all_in_class_subdock (icon);
306 			break;
307 			case 2:  // minimise
308 				_cairo_dock_hide_show_in_class_subdock (icon);
309 			break;
310 			case 3:  // launch new
311 				if (icon->cCommand != NULL)
312 				{
313 					gldi_object_notify (CAIRO_CONTAINER (pDock), NOTIFICATION_CLICK_ICON, icon, pDock, GDK_SHIFT_MASK);  // on emule un shift+clic gauche .
314 				}
315 			break;
316 		}
317 
318 		return GLDI_NOTIFICATION_INTERCEPT;
319 	}
320 	return GLDI_NOTIFICATION_LET_PASS;
321 }
322 
323 
cairo_dock_notification_scroll_icon(G_GNUC_UNUSED gpointer pUserData,Icon * icon,G_GNUC_UNUSED GldiContainer * pContainer,int iDirection)324 gboolean cairo_dock_notification_scroll_icon (G_GNUC_UNUSED gpointer pUserData, Icon *icon, G_GNUC_UNUSED GldiContainer *pContainer, int iDirection)
325 {
326 	if (CAIRO_DOCK_IS_MULTI_APPLI (icon) || CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon))  // on emule un alt+tab sur la liste des applis du sous-dock.
327 	{
328 		_cairo_dock_show_prev_next_in_subdock (icon, iDirection == GDK_SCROLL_DOWN);
329 	}
330 	else if (CAIRO_DOCK_IS_APPLI (icon) && icon->cClass != NULL)
331 	{
332 		Icon *pNextIcon = cairo_dock_get_prev_next_classmate_icon (icon, iDirection == GDK_SCROLL_DOWN);
333 		if (pNextIcon != NULL)
334 			gldi_window_show (pNextIcon->pAppli);
335 	}
336 	return GLDI_NOTIFICATION_LET_PASS;
337 }
338 
339 
cairo_dock_notification_drop_data(G_GNUC_UNUSED gpointer pUserData,const gchar * cReceivedData,Icon * icon,double fOrder,GldiContainer * pContainer)340 gboolean cairo_dock_notification_drop_data (G_GNUC_UNUSED gpointer pUserData, const gchar *cReceivedData, Icon *icon, double fOrder, GldiContainer *pContainer)
341 {
342 	cd_debug ("take the drop");
343 	if (! CAIRO_DOCK_IS_DOCK (pContainer))
344 		return GLDI_NOTIFICATION_LET_PASS;
345 
346 	CairoDock *pDock = CAIRO_DOCK (pContainer);
347 	CairoDock *pReceivingDock = pDock;
348 	if (g_str_has_suffix (cReceivedData, ".desktop"))  // .desktop -> add a new launcher if dropped on or amongst launchers.
349 	{
350 		cd_debug (" dropped a .desktop");
351 		if (! myTaskbarParam.bMixLauncherAppli && CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon))
352 			return GLDI_NOTIFICATION_LET_PASS;
353 		cd_debug (" add it");
354 		if (fOrder == CAIRO_DOCK_LAST_ORDER && CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon) && icon->pSubDock != NULL)  // drop onto a container icon.
355 		{
356 			pReceivingDock = icon->pSubDock;  // -> add into the pointed sub-dock.
357 		}
358 	}
359 	else  // file.
360 	{
361 		if (icon != NULL && fOrder == CAIRO_DOCK_LAST_ORDER)  // dropped on an icon
362 		{
363 			if (CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (icon))  // sub-dock -> propagate to the sub-dock.
364 			{
365 				pReceivingDock = icon->pSubDock;
366 			}
367 			else if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (icon)
368 			|| CAIRO_DOCK_ICON_TYPE_IS_APPLI (icon)
369 			|| CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (icon)) // launcher/appli -> fire the command with this file.
370 			{
371 				if (icon->cCommand == NULL)
372 					return GLDI_NOTIFICATION_LET_PASS;
373 				gchar *cCommand;
374 				if (strncmp (cReceivedData, "file://", 7) == 0)  // tous les programmes ne gerent pas les URI; pour parer au cas ou il ne le gererait pas, dans le cas d'un fichier local, on convertit en un chemin
375 				{
376 					gchar *cPath = g_filename_from_uri (cReceivedData, NULL, NULL);
377 					cCommand = g_strdup_printf ("%s \"%s\"", icon->cCommand, cPath);
378 					g_free (cPath);
379 				}
380 				else
381 					cCommand = g_strdup_printf ("%s \"%s\"", icon->cCommand, cReceivedData);
382 				cd_message ("will open the file with the command '%s'...", cCommand);
383 				g_spawn_command_line_async (cCommand, NULL);
384 				g_free (cCommand);
385 				gldi_icon_request_animation (icon, "blink", 2);
386 				return GLDI_NOTIFICATION_INTERCEPT;
387 			}
388 			else  // skip any other case.
389 			{
390 				return GLDI_NOTIFICATION_LET_PASS;
391 			}
392 		}  // else: dropped between 2 icons -> try to add it (for instance a script).
393 	}
394 
395 	if (g_bLocked || myDocksParam.bLockAll)
396 		return GLDI_NOTIFICATION_LET_PASS;
397 
398 	Icon *pNewIcon = gldi_launcher_add_new (cReceivedData, pReceivingDock, fOrder);
399 
400 	return (pNewIcon ? GLDI_NOTIFICATION_INTERCEPT : GLDI_NOTIFICATION_LET_PASS);
401 }
402 
403 
cairo_dock_set_custom_icon_on_appli(const gchar * cFilePath,Icon * icon,GldiContainer * pContainer)404 void cairo_dock_set_custom_icon_on_appli (const gchar *cFilePath, Icon *icon, GldiContainer *pContainer)
405 {
406 	g_return_if_fail (CAIRO_DOCK_IS_APPLI (icon) && cFilePath != NULL);
407 	gchar *ext = strrchr (cFilePath, '.');
408 	if (!ext)
409 		return;
410 	cd_debug ("%s (%s - %s)", __func__, cFilePath, icon->cFileName);
411 	if ((strcmp (ext, ".png") == 0 || strcmp (ext, ".svg") == 0) && !myDocksParam.bLockAll) // && ! myDocksParam.bLockIcons) // or if we have to hide the option...
412 	{
413 		if (!myTaskbarParam.bOverWriteXIcons)
414 		{
415 			myTaskbarParam.bOverWriteXIcons = TRUE;
416 			cairo_dock_update_conf_file (g_cConfFile,
417 				G_TYPE_BOOLEAN, "TaskBar", "overwrite xicon", myTaskbarParam.bOverWriteXIcons,
418 				G_TYPE_INVALID);
419 			gldi_dialog_show_temporary_with_default_icon (_("The option 'overwrite X icons' has been automatically enabled in the config.\nIt is located in the 'Taskbar' module."), icon, pContainer, 6000);
420 		}
421 
422 		gchar *cPath = NULL;
423 		if (strncmp (cFilePath, "file://", 7) == 0)
424 		{
425 			cPath = g_filename_from_uri (cFilePath, NULL, NULL);
426 		}
427 
428 		const gchar *cClassIcon = cairo_dock_get_class_icon (icon->cClass);
429 		if (cClassIcon == NULL)
430 			cClassIcon = icon->cClass;
431 
432 		gchar *cDestPath = g_strdup_printf ("%s/%s%s", g_cCurrentIconsPath, cClassIcon, ext);
433 		cairo_dock_copy_file (cPath?cPath:cFilePath, cDestPath);
434 		g_free (cDestPath);
435 		g_free (cPath);
436 
437 		cairo_dock_reload_icon_image (icon, pContainer);
438 		cairo_dock_redraw_icon (icon);
439 	}
440 }
441 
442 
cairo_dock_notification_configure_desklet(G_GNUC_UNUSED gpointer pUserData,CairoDesklet * pDesklet)443 gboolean cairo_dock_notification_configure_desklet (G_GNUC_UNUSED gpointer pUserData, CairoDesklet *pDesklet)
444 {
445 	//g_print ("desklet %s configured\n", pDesklet->pIcon?pDesklet->pIcon->cName:"unknown");
446 	cairo_dock_gui_update_desklet_params (pDesklet);
447 
448 	return GLDI_NOTIFICATION_LET_PASS;
449 }
450 
cairo_dock_notification_icon_moved(G_GNUC_UNUSED gpointer pUserData,Icon * pIcon,G_GNUC_UNUSED CairoDock * pDock)451 gboolean cairo_dock_notification_icon_moved (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, G_GNUC_UNUSED CairoDock *pDock)
452 {
453 	//g_print ("icon %s moved\n", pIcon?pIcon->cName:"unknown");
454 
455 	if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon)
456 	|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (pIcon)
457 	|| (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon) && pIcon->cDesktopFileName)
458 	|| CAIRO_DOCK_ICON_TYPE_IS_APPLET (pIcon))
459 		cairo_dock_gui_trigger_reload_items ();
460 
461 	return GLDI_NOTIFICATION_LET_PASS;
462 }
463 
cairo_dock_notification_icon_inserted(G_GNUC_UNUSED gpointer pUserData,Icon * pIcon,G_GNUC_UNUSED CairoDock * pDock)464 gboolean cairo_dock_notification_icon_inserted (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, G_GNUC_UNUSED CairoDock *pDock)
465 {
466 	//g_print ("icon %s inserted (%.2f)\n", pIcon?pIcon->cName:"unknown", pIcon->fInsertRemoveFactor);
467 	//if (pIcon->fInsertRemoveFactor == 0)
468 	//	return GLDI_NOTIFICATION_LET_PASS;
469 
470 	if ( ( (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon)
471 	|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (pIcon)
472 	|| CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) && pIcon->cDesktopFileName)
473 	|| CAIRO_DOCK_ICON_TYPE_IS_APPLET (pIcon))
474 		cairo_dock_gui_trigger_reload_items ();
475 
476 	return GLDI_NOTIFICATION_LET_PASS;
477 }
478 
cairo_dock_notification_icon_removed(G_GNUC_UNUSED gpointer pUserData,Icon * pIcon,G_GNUC_UNUSED CairoDock * pDock)479 gboolean cairo_dock_notification_icon_removed (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, G_GNUC_UNUSED CairoDock *pDock)
480 {
481 	//g_print ("icon %s removed (%.2f)\n", pIcon?pIcon->cName:"unknown", pIcon->fInsertRemoveFactor);
482 	//if (pIcon->fInsertRemoveFactor == 0)
483 	//	return GLDI_NOTIFICATION_LET_PASS;
484 
485 	if ( ( (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon)
486 	|| CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (pIcon)
487 	|| CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon)) && pIcon->cDesktopFileName)
488 	|| CAIRO_DOCK_ICON_TYPE_IS_APPLET (pIcon))
489 		cairo_dock_gui_trigger_reload_items ();
490 
491 	return GLDI_NOTIFICATION_LET_PASS;
492 }
493 
cairo_dock_notification_desklet_added_removed(G_GNUC_UNUSED gpointer pUserData,G_GNUC_UNUSED CairoDesklet * pDesklet)494 gboolean cairo_dock_notification_desklet_added_removed (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED CairoDesklet *pDesklet)
495 {
496 	//Icon *pIcon = pDesklet->pIcon;
497 	//g_print ("desklet %s removed\n", pIcon?pIcon->cName:"unknown");
498 
499 	cairo_dock_gui_trigger_reload_items ();
500 
501 	return GLDI_NOTIFICATION_LET_PASS;
502 }
503 
cairo_dock_notification_dock_destroyed(G_GNUC_UNUSED gpointer pUserData,G_GNUC_UNUSED CairoDock * pDock)504 gboolean cairo_dock_notification_dock_destroyed (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED CairoDock *pDock)
505 {
506 	//g_print ("dock destroyed\n");
507 	cairo_dock_gui_trigger_reload_items ();
508 
509 	return GLDI_NOTIFICATION_LET_PASS;
510 }
511 
cairo_dock_notification_module_activated(G_GNUC_UNUSED gpointer pUserData,const gchar * cModuleName,G_GNUC_UNUSED gboolean bActivated)512 gboolean cairo_dock_notification_module_activated (G_GNUC_UNUSED gpointer pUserData, const gchar *cModuleName, G_GNUC_UNUSED gboolean bActivated)
513 {
514 	//g_print ("module %s (de)activated (%d)\n", cModuleName, bActivated);
515 	cairo_dock_gui_trigger_update_module_state (cModuleName);
516 
517 	cairo_dock_gui_trigger_reload_items ();  // for plug-ins that don't have an applet, like Cairo-Pinguin.
518 
519 	return GLDI_NOTIFICATION_LET_PASS;
520 }
521 
cairo_dock_notification_module_registered(G_GNUC_UNUSED gpointer pUserData,G_GNUC_UNUSED const gchar * cModuleName,G_GNUC_UNUSED gboolean bRegistered)522 gboolean cairo_dock_notification_module_registered (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED const gchar *cModuleName, G_GNUC_UNUSED gboolean bRegistered)
523 {
524 	//g_print ("module %s (un)registered (%d)\n", cModuleName, bRegistered);
525 	cairo_dock_gui_trigger_update_modules_list ();
526 
527 	return GLDI_NOTIFICATION_LET_PASS;
528 }
529 
cairo_dock_notification_module_detached(G_GNUC_UNUSED gpointer pUserData,GldiModuleInstance * pInstance,gboolean bIsDetached)530 gboolean cairo_dock_notification_module_detached (G_GNUC_UNUSED gpointer pUserData, GldiModuleInstance *pInstance, gboolean bIsDetached)
531 {
532 	//g_print ("module %s (de)tached (%d)\n", pInstance->pModule->pVisitCard->cModuleName, bIsDetached);
533 	cairo_dock_gui_trigger_update_module_container (pInstance, bIsDetached);
534 
535 	cairo_dock_gui_trigger_reload_items ();
536 
537 	return GLDI_NOTIFICATION_LET_PASS;
538 }
539 
cairo_dock_notification_shortkey_added_removed_changed(G_GNUC_UNUSED gpointer pUserData,G_GNUC_UNUSED GldiShortkey * pShortkey)540 gboolean cairo_dock_notification_shortkey_added_removed_changed (G_GNUC_UNUSED gpointer pUserData, G_GNUC_UNUSED GldiShortkey *pShortkey)
541 {
542 	cairo_dock_gui_trigger_reload_shortkeys ();
543 
544 	return GLDI_NOTIFICATION_LET_PASS;
545 }
546