~ubuntu-branches/ubuntu/oneiric/cairo-dock/oneiric

« back to all changes in this revision

Viewing changes to src/cairo-dock-user-interaction.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: (18.1.1 cairo-dock) (19.1.1 cairo-dock)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <math.h>
 
21
#include <sys/time.h>
 
22
#include <string.h>
 
23
#include <stdlib.h>
 
24
#include <unistd.h>
 
25
#include <cairo.h>
 
26
#include <gdk/gdkkeysyms.h>
 
27
#include <gtk/gtk.h>
 
28
 
 
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"
 
49
 
 
50
extern gboolean g_bLocked;
 
51
extern gchar *g_cConfFile;
 
52
extern gchar *g_cCurrentIconsPath;
 
53
 
 
54
static int _compare_zorder (Icon *icon1, Icon *icon2)  // classe par z-order decroissant.
 
55
{
 
56
        if (icon1->iStackOrder < icon2->iStackOrder)
 
57
                return -1;
 
58
        else if (icon1->iStackOrder > icon2->iStackOrder)
 
59
                return 1;
 
60
        else
 
61
                return 0;
 
62
}
 
63
static void _cairo_dock_hide_show_in_class_subdock (Icon *icon)
 
64
{
 
65
        Icon *pIcon;
 
66
        GList *ic;
 
67
        for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
 
68
        {
 
69
                pIcon = ic->data;
 
70
                if (pIcon->Xid != 0 && ! pIcon->bIsHidden)  // par defaut on cache tout.
 
71
                {
 
72
                        break;
 
73
                }
 
74
        }
 
75
        
 
76
        if (ic != NULL)  // au moins une fenetre est visible, on cache tout.
 
77
        {
 
78
                for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
 
79
                {
 
80
                        pIcon = ic->data;
 
81
                        if (pIcon->Xid != 0 && ! pIcon->bIsHidden)
 
82
                        {
 
83
                                cairo_dock_minimize_xwindow (pIcon->Xid);
 
84
                        }
 
85
                }
 
86
        }
 
87
        else  // on montre tout, dans l'ordre du z-order.
 
88
        {
 
89
                GList *pZOrderList = NULL;
 
90
                for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
 
91
                {
 
92
                        pIcon = ic->data;
 
93
                        if (pIcon->Xid != 0)
 
94
                                pZOrderList = g_list_insert_sorted (pZOrderList, pIcon, (GCompareFunc) _compare_zorder);
 
95
                }
 
96
                for (ic = pZOrderList; ic != NULL; ic = ic->next)
 
97
                {
 
98
                        pIcon = ic->data;
 
99
                        cairo_dock_show_xwindow (pIcon->Xid);
 
100
                }
 
101
                g_list_free (pZOrderList);
 
102
        }
 
103
}
 
104
 
 
105
static void _cairo_dock_show_prev_next_in_subdock (Icon *icon, gboolean bNext)
 
106
{
 
107
        Window xActiveId = cairo_dock_get_current_active_window ();
 
108
        GList *ic;
 
109
        Icon *pIcon;
 
110
        for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
 
111
        {
 
112
                pIcon = ic->data;
 
113
                if (pIcon->Xid == xActiveId)
 
114
                        break;
 
115
        }
 
116
        if (ic == NULL)
 
117
                ic = icon->pSubDock->icons;
 
118
        
 
119
        GList *ic2 = ic;
 
120
        do
 
121
        {
 
122
                ic2 = (bNext ? cairo_dock_get_next_element (ic2, icon->pSubDock->icons) : cairo_dock_get_previous_element (ic2, icon->pSubDock->icons));
 
123
                pIcon = ic2->data;
 
124
                if (CAIRO_DOCK_IS_APPLI (pIcon))
 
125
                {
 
126
                        cairo_dock_show_xwindow (pIcon->Xid);
 
127
                        break;
 
128
                }
 
129
        } while (ic2 != ic);
 
130
}
 
131
 
 
132
static void _cairo_dock_close_all_in_class_subdock (Icon *icon)
 
133
{
 
134
        Icon *pIcon;
 
135
        GList *ic;
 
136
        for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
 
137
        {
 
138
                pIcon = ic->data;
 
139
                if (pIcon->Xid != 0)
 
140
                {
 
141
                        cairo_dock_close_xwindow (pIcon->Xid);
 
142
                }
 
143
        }
 
144
}
 
145
 
 
146
gboolean cairo_dock_notification_click_icon (gpointer pUserData, Icon *icon, CairoDock *pDock, guint iButtonState)
 
147
{
 
148
        //g_print ("+ %s (%s)\n", __func__, icon ? icon->cName : "no icon");
 
149
        if (icon == NULL)
 
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.
 
152
        {
 
153
                cairo_dock_show_subdock (icon, pDock);
 
154
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
155
        }
 
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.
 
157
        {
 
158
                cd_debug (" appli");
 
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);
 
161
                else
 
162
                        cairo_dock_show_xwindow (icon->Xid);
 
163
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
164
        }
 
165
        else if (CAIRO_DOCK_IS_LAUNCHER (icon))
 
166
        {
 
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.
 
169
                {
 
170
                        if (! myAccessibility.bShowSubDockOnClick)
 
171
                        {
 
172
                                _cairo_dock_hide_show_in_class_subdock (icon);
 
173
                        }
 
174
                        return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
175
                }
 
176
                else if (icon->cCommand != NULL && strcmp (icon->cCommand, "none") != 0)  // finalement, on lance la commande.
 
177
                {
 
178
                        if (pDock->iRefCount != 0)
 
179
                        {
 
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;
 
183
                        }
 
184
                        
 
185
                        gboolean bSuccess = FALSE;
 
186
                        if (*icon->cCommand == '<')
 
187
                        {
 
188
                                bSuccess = cairo_dock_simulate_key_sequence (icon->cCommand);
 
189
                                if (!bSuccess)
 
190
                                        bSuccess = cairo_dock_launch_command_full (icon->cCommand, icon->cWorkingDirectory);
 
191
                        }
 
192
                        else
 
193
                        {
 
194
                                bSuccess = cairo_dock_launch_command_full (icon->cCommand, icon->cWorkingDirectory);
 
195
                                if (! bSuccess)
 
196
                                        bSuccess = cairo_dock_simulate_key_sequence (icon->cCommand);
 
197
                        }
 
198
                        if (! bSuccess)
 
199
                        {
 
200
                                cairo_dock_request_icon_animation (icon, pDock, "blink", 1);  // 1 clignotement si echec
 
201
                        }
 
202
                        return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
203
                }
 
204
        }
 
205
        else
 
206
                cd_debug ("no action here");
 
207
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
208
}
 
209
 
 
210
 
 
211
gboolean cairo_dock_notification_middle_click_icon (gpointer pUserData, Icon *icon, CairoDock *pDock)
 
212
{
 
213
        if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.bCloseAppliOnMiddleClick && ! CAIRO_DOCK_IS_APPLET (icon))
 
214
        {
 
215
                cairo_dock_close_xwindow (icon->Xid);
 
216
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
217
        }
 
218
        if (CAIRO_DOCK_IS_URI_LAUNCHER (icon) && icon->pSubDock != NULL)  // icone de repertoire.
 
219
        {
 
220
                cairo_dock_fm_launch_uri (icon->cCommand);
 
221
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
222
        }
 
223
        if (CAIRO_DOCK_IS_MULTI_APPLI (icon))
 
224
        {
 
225
                // On ferme tout.
 
226
                _cairo_dock_close_all_in_class_subdock (icon);
 
227
                
 
228
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
229
        }
 
230
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
231
}
 
232
 
 
233
 
 
234
gboolean cairo_dock_notification_scroll_icon (gpointer pUserData, Icon *icon, CairoDock *pDock, int iDirection)
 
235
{
 
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.
 
237
        {
 
238
                _cairo_dock_show_prev_next_in_subdock (icon, iDirection == GDK_SCROLL_DOWN);
 
239
        }
 
240
        else if (CAIRO_DOCK_IS_APPLI (icon) && icon->cClass != NULL)
 
241
        {
 
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);
 
245
        }
 
246
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
247
}
 
248
 
 
249
 
 
250
gboolean cairo_dock_notification_drop_data (gpointer pUserData, const gchar *cReceivedData, Icon *icon, double fOrder, CairoContainer *pContainer)
 
251
{
 
252
        if (! CAIRO_DOCK_IS_DOCK (pContainer))
 
253
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
254
        
 
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.
 
258
        {
 
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.
 
264
                {
 
265
                        pReceivingDock = icon->pSubDock;
 
266
                }
 
267
        }
 
268
        else  // c'est un fichier.
 
269
        {
 
270
                if (fOrder == CAIRO_DOCK_LAST_ORDER)  // on a lache dessus.
 
271
                {
 
272
                        if (CAIRO_DOCK_IS_LAUNCHER (icon))
 
273
                        {
 
274
                                if (CAIRO_DOCK_IS_URI_LAUNCHER (icon))
 
275
                                {
 
276
                                        if (icon->pSubDock != NULL || icon->iVolumeID != 0)  // on le lache sur un repertoire ou un point de montage.
 
277
                                        {
 
278
                                                cairo_dock_fm_move_into_directory (cReceivedData, icon, pContainer);
 
279
                                                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
280
                                        }
 
281
                                        else  // on le lache sur un fichier.
 
282
                                        {
 
283
                                                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
284
                                        }
 
285
                                }
 
286
                                else if (CAIRO_DOCK_IS_CONTAINER_LAUNCHER (icon))  // on le lache sur un sous-dock de lanceurs.
 
287
                                {
 
288
                                        pReceivingDock = icon->pSubDock;
 
289
                                }
 
290
                                else  // on le lache sur un lanceur.
 
291
                                {
 
292
                                        gchar *cPath = NULL;
 
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
 
294
                                        {
 
295
                                                cPath = g_filename_from_uri (cReceivedData, NULL, NULL);
 
296
                                        }
 
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);
 
300
                                        g_free (cPath);
 
301
                                        g_free (cCommand);
 
302
                                        cairo_dock_request_icon_animation (icon, pDock, "blink", 2);
 
303
                                        return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
304
                                }
 
305
                        }
 
306
                        else if (CAIRO_DOCK_IS_APPLI (icon))  // une appli normale
 
307
                        {
 
308
                                gchar *ext = strrchr (cReceivedData, '.');
 
309
                                if (!ext)
 
310
                                        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
311
                                if ((strcmp (ext, ".png") == 0 || strcmp (ext, ".svg") == 0) && !myAccessibility.bLockAll && ! myAccessibility.bLockIcons)
 
312
                                {
 
313
                                        if (!myTaskBar.bOverWriteXIcons)
 
314
                                        {
 
315
                                                myTaskBar.bOverWriteXIcons = TRUE;
 
316
                                                cairo_dock_update_conf_file (g_cConfFile,
 
317
                                                        G_TYPE_BOOLEAN, "TaskBar", "overwrite xicon", myTaskBar.bOverWriteXIcons,
 
318
                                                        G_TYPE_INVALID);
 
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);
 
320
                                        }
 
321
                                        
 
322
                                        gchar *cPath = NULL;
 
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
 
324
                                        {
 
325
                                                cPath = g_filename_from_uri (cReceivedData, NULL, NULL);
 
326
                                        }
 
327
                                        
 
328
                                        gchar *cCommand = g_strdup_printf ("cp '%s' '%s/%s%s'", cPath?cPath:cReceivedData, g_cCurrentIconsPath, icon->cClass, ext);
 
329
                                        int r = system (cCommand);
 
330
                                        g_free (cCommand);
 
331
                                        
 
332
                                        cairo_dock_reload_icon_image (icon, pContainer);
 
333
                                        cairo_dock_redraw_icon (icon, pContainer);
 
334
                                }
 
335
                                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
336
                        }
 
337
                        else  // autre chose.
 
338
                        {
 
339
                                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
340
                        }
 
341
                }
 
342
                else  // on a lache a cote.
 
343
                {
 
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.
 
346
                        {
 
347
                                cairo_dock_fm_move_into_directory (cReceivedData, icon, pContainer);
 
348
                                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
 
349
                        }
 
350
                }
 
351
        }
 
352
 
 
353
        if (g_bLocked || myAccessibility.bLockAll)
 
354
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
355
        
 
356
        cairo_dock_add_new_launcher_by_uri (cReceivedData, pReceivingDock, fOrder);
 
357
        
 
358
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
359
}