2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
26
#include <gdk/gdkkeysyms.h>
29
#include "cairo-dock-animations.h"
30
#include "cairo-dock-icons.h"
31
#include "cairo-dock-applications-manager.h"
32
#include "cairo-dock-application-facility.h"
33
#include "cairo-dock-desktop-file-factory.h"
34
#include "cairo-dock-launcher-manager.h"
35
#include "cairo-dock-dock-facility.h"
36
#include "cairo-dock-notifications.h"
37
#include "cairo-dock-dialog-manager.h"
38
#include "cairo-dock-file-manager.h"
39
#include "cairo-dock-log.h"
40
#include "cairo-dock-dock-manager.h"
41
#include "cairo-dock-keybinder.h"
42
#include "cairo-dock-animations.h"
43
#include "cairo-dock-internal-accessibility.h"
44
#include "cairo-dock-internal-taskbar.h"
45
#include "cairo-dock-internal-icons.h"
46
#include "cairo-dock-class-manager.h"
47
#include "cairo-dock-X-utilities.h"
48
#include "cairo-dock-user-interaction.h"
50
extern gboolean g_bLocked;
51
extern gchar *g_cConfFile;
52
extern gchar *g_cCurrentIconsPath;
54
static int _compare_zorder (Icon *icon1, Icon *icon2) // classe par z-order decroissant.
56
if (icon1->iStackOrder < icon2->iStackOrder)
58
else if (icon1->iStackOrder > icon2->iStackOrder)
63
static void _cairo_dock_hide_show_in_class_subdock (Icon *icon)
67
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
70
if (pIcon->Xid != 0 && ! pIcon->bIsHidden) // par defaut on cache tout.
76
if (ic != NULL) // au moins une fenetre est visible, on cache tout.
78
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
81
if (pIcon->Xid != 0 && ! pIcon->bIsHidden)
83
cairo_dock_minimize_xwindow (pIcon->Xid);
87
else // on montre tout, dans l'ordre du z-order.
89
GList *pZOrderList = NULL;
90
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
94
pZOrderList = g_list_insert_sorted (pZOrderList, pIcon, (GCompareFunc) _compare_zorder);
96
for (ic = pZOrderList; ic != NULL; ic = ic->next)
99
cairo_dock_show_xwindow (pIcon->Xid);
101
g_list_free (pZOrderList);
105
static void _cairo_dock_show_prev_next_in_subdock (Icon *icon, gboolean bNext)
107
Window xActiveId = cairo_dock_get_current_active_window ();
110
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
113
if (pIcon->Xid == xActiveId)
117
ic = icon->pSubDock->icons;
122
ic2 = (bNext ? cairo_dock_get_next_element (ic2, icon->pSubDock->icons) : cairo_dock_get_previous_element (ic2, icon->pSubDock->icons));
124
if (CAIRO_DOCK_IS_APPLI (pIcon))
126
cairo_dock_show_xwindow (pIcon->Xid);
132
static void _cairo_dock_close_all_in_class_subdock (Icon *icon)
136
for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
141
cairo_dock_close_xwindow (pIcon->Xid);
146
gboolean cairo_dock_notification_click_icon (gpointer pUserData, Icon *icon, CairoDock *pDock, guint iButtonState)
148
//g_print ("+ %s (%s)\n", __func__, icon ? icon->cName : "no icon");
150
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
151
if (icon->pSubDock != NULL && (myAccessibility.bShowSubDockOnClick || !GTK_WIDGET_VISIBLE (icon->pSubDock->container.pWidget)) && ! (iButtonState & GDK_SHIFT_MASK)) // icone de sous-dock a montrer au clic.
153
cairo_dock_show_subdock (icon, pDock);
154
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
156
else if (CAIRO_DOCK_IS_APPLI (icon) && ! ((iButtonState & GDK_SHIFT_MASK) && CAIRO_DOCK_IS_LAUNCHER (icon)) && ! CAIRO_DOCK_IS_APPLET (icon)) // une icone d'appli ou d'inhibiteur (hors applet) mais sans le shift+clic : on cache ou on montre.
159
if (cairo_dock_get_current_active_window () == icon->Xid && myTaskBar.bMinimizeOnClick) // ne marche que si le dock est une fenĆŖtre de type 'dock', sinon il prend le focus.
160
cairo_dock_minimize_xwindow (icon->Xid);
162
cairo_dock_show_xwindow (icon->Xid);
163
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
165
else if (CAIRO_DOCK_IS_LAUNCHER (icon))
167
//g_print ("+ launcher\n");
168
if (CAIRO_DOCK_IS_MULTI_APPLI (icon) && ! (iButtonState & GDK_SHIFT_MASK)) // un lanceur ayant un sous-dock de classe ou une icone de paille : on cache ou on montre.
170
if (! myAccessibility.bShowSubDockOnClick)
172
_cairo_dock_hide_show_in_class_subdock (icon);
174
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
176
else if (icon->cCommand != NULL && strcmp (icon->cCommand, "none") != 0) // finalement, on lance la commande.
178
if (pDock->iRefCount != 0)
180
Icon *pMainIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
181
if (CAIRO_DOCK_IS_APPLET (pMainIcon))
182
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
185
gboolean bSuccess = FALSE;
186
if (*icon->cCommand == '<')
188
bSuccess = cairo_dock_simulate_key_sequence (icon->cCommand);
190
bSuccess = cairo_dock_launch_command_full (icon->cCommand, icon->cWorkingDirectory);
194
bSuccess = cairo_dock_launch_command_full (icon->cCommand, icon->cWorkingDirectory);
196
bSuccess = cairo_dock_simulate_key_sequence (icon->cCommand);
200
cairo_dock_request_icon_animation (icon, pDock, "blink", 1); // 1 clignotement si echec
202
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
206
cd_debug ("no action here");
207
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
211
gboolean cairo_dock_notification_middle_click_icon (gpointer pUserData, Icon *icon, CairoDock *pDock)
213
if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.bCloseAppliOnMiddleClick && ! CAIRO_DOCK_IS_APPLET (icon))
215
cairo_dock_close_xwindow (icon->Xid);
216
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
218
if (CAIRO_DOCK_IS_URI_LAUNCHER (icon) && icon->pSubDock != NULL) // icone de repertoire.
220
cairo_dock_fm_launch_uri (icon->cCommand);
221
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
223
if (CAIRO_DOCK_IS_MULTI_APPLI (icon))
226
_cairo_dock_close_all_in_class_subdock (icon);
228
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
230
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
234
gboolean cairo_dock_notification_scroll_icon (gpointer pUserData, Icon *icon, CairoDock *pDock, int iDirection)
236
if (CAIRO_DOCK_IS_MULTI_APPLI (icon) || CAIRO_DOCK_IS_CONTAINER_LAUNCHER (icon)) // on emule un alt+tab sur la liste des applis du sous-dock.
238
_cairo_dock_show_prev_next_in_subdock (icon, iDirection == GDK_SCROLL_DOWN);
240
else if (CAIRO_DOCK_IS_APPLI (icon) && icon->cClass != NULL)
242
Icon *pNextIcon = cairo_dock_get_prev_next_classmate_icon (icon, iDirection == GDK_SCROLL_DOWN);
243
if (pNextIcon != NULL)
244
cairo_dock_show_xwindow (pNextIcon->Xid);
246
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
250
gboolean cairo_dock_notification_drop_data (gpointer pUserData, const gchar *cReceivedData, Icon *icon, double fOrder, CairoContainer *pContainer)
252
if (! CAIRO_DOCK_IS_DOCK (pContainer))
253
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
255
CairoDock *pDock = CAIRO_DOCK (pContainer);
256
CairoDock *pReceivingDock = pDock;
257
if (g_str_has_suffix (cReceivedData, ".desktop")) // ajout d'un nouveau lanceur si on a lache sur ou entre 2 lanceurs.
259
if ((myIcons.iSeparateIcons == 1 || myIcons.iSeparateIcons == 3) && CAIRO_DOCK_IS_NORMAL_APPLI (icon))
260
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
261
if ((myIcons.iSeparateIcons == 2 || myIcons.iSeparateIcons == 3) && CAIRO_DOCK_IS_APPLET (icon))
262
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
263
if (fOrder == CAIRO_DOCK_LAST_ORDER && icon && icon->pSubDock != NULL) // on a lache sur une icone de sous-dock => on l'ajoute dans le sous-dock.
265
pReceivingDock = icon->pSubDock;
268
else // c'est un fichier.
270
if (fOrder == CAIRO_DOCK_LAST_ORDER) // on a lache dessus.
272
if (CAIRO_DOCK_IS_LAUNCHER (icon))
274
if (CAIRO_DOCK_IS_URI_LAUNCHER (icon))
276
if (icon->pSubDock != NULL || icon->iVolumeID != 0) // on le lache sur un repertoire ou un point de montage.
278
cairo_dock_fm_move_into_directory (cReceivedData, icon, pContainer);
279
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
281
else // on le lache sur un fichier.
283
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
286
else if (CAIRO_DOCK_IS_CONTAINER_LAUNCHER (icon)) // on le lache sur un sous-dock de lanceurs.
288
pReceivingDock = icon->pSubDock;
290
else // on le lache sur un lanceur.
293
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
295
cPath = g_filename_from_uri (cReceivedData, NULL, NULL);
297
gchar *cCommand = g_strdup_printf ("%s \"%s\"", icon->cCommand, cPath ? cPath : cReceivedData);
298
cd_message ("will open the file with the command '%s'...\n", cCommand);
299
g_spawn_command_line_async (cCommand, NULL);
302
cairo_dock_request_icon_animation (icon, pDock, "blink", 2);
303
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
306
else if (CAIRO_DOCK_IS_APPLI (icon)) // une appli normale
308
gchar *ext = strrchr (cReceivedData, '.');
310
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
311
if ((strcmp (ext, ".png") == 0 || strcmp (ext, ".svg") == 0) && !myAccessibility.bLockAll && ! myAccessibility.bLockIcons)
313
if (!myTaskBar.bOverWriteXIcons)
315
myTaskBar.bOverWriteXIcons = TRUE;
316
cairo_dock_update_conf_file (g_cConfFile,
317
G_TYPE_BOOLEAN, "TaskBar", "overwrite xicon", myTaskBar.bOverWriteXIcons,
319
cairo_dock_show_temporary_dialog_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);
323
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
325
cPath = g_filename_from_uri (cReceivedData, NULL, NULL);
328
gchar *cCommand = g_strdup_printf ("cp '%s' '%s/%s%s'", cPath?cPath:cReceivedData, g_cCurrentIconsPath, icon->cClass, ext);
329
int r = system (cCommand);
332
cairo_dock_reload_icon_image (icon, pContainer);
333
cairo_dock_redraw_icon (icon, pContainer);
335
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
339
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
342
else // on a lache a cote.
344
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
345
if (CAIRO_DOCK_IS_URI_LAUNCHER (pPointingIcon)) // on a lache dans un dock qui est un repertoire, on copie donc le fichier dedans.
347
cairo_dock_fm_move_into_directory (cReceivedData, icon, pContainer);
348
return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
353
if (g_bLocked || myAccessibility.bLockAll)
354
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
356
cairo_dock_add_new_launcher_by_uri (cReceivedData, pReceivingDock, fOrder);
358
return CAIRO_DOCK_LET_PASS_NOTIFICATION;