~ubuntu-branches/ubuntu/trusty/cairo-dock-plug-ins/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/bzr3047-3048_Status-Notifier_Added_support_of_middle_click_and_scroll.patch/Status-Notifier/src/applet-notifications.c

  • Committer: Package Import Robot
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2014-04-07 00:48:03 UTC
  • mfrom: (48.1.3 cairo-dock-plug-ins)
  • Revision ID: package-import@ubuntu.com-20140407004803-5s5leqg9iplbngje
Tags: 3.3.99.beta1.2.really.3.3.2-0ubuntu1
* Revert back to the 3.3.2 version: (LP: #1302246)
  Unfortunately, due to the lack of time, we have to revert back to the
  latest stable version. Sorry for that but feel free to help us ;-)
* debian/patches: cherry-pick patches from upstream BZR repo, all 'bug-fix'
  and changes that were already in the 3.3.99.beta1 version except all
  changes linked to the new style, the menu and the configuration.
  - bzr3008_GMenu_new_apps_in_the_list.patch: GMenu: New Apps: if there are
    new apps when the 'new apps' dialogue is opened, add these new apps in
    the list
  - bzr3010_GMenu_option_hide_new_apps_dialogue.patch: GMenu: Config: Added
    the possibility to not display notification to quickly launch new apps
  - bzr3021_Terminal_launch_default_terminal_middle_click.patch: Terminal:
    middle click: launch the default terminal
  - bzr3031-3032_GMenu_remove_empty_submenus.patch: GMenu: do not add empty
    submenus when creating them and remove empty submenus
  - bzr3035_DND2Share_History_was_empty.patch: DnD2Share: history menu was
    empty
  - bzr3036-3040_Shortcuts_removed_disk_usage_on_bookmarks_and_support_
    x-nautilus_URI.patch: Shortcuts: correctly removed an old bookmark ;
    added support for x-nautilus-(...) URI ; avoid duplicated code +
    bookmarks doesn't have a disk usage ; translated a few sentences from
    French to English
  - bzr3043_Fixed_typo_with_some_sentences.patch: Fixed typo with some
    sentences which were not correctly translated
  - bzr3045-3046_GVFS_support_x-nautilus-desktop_and_fixed_typos_and_memory_
    leaks.patch: gvfs: fixed typo and tiny memory leak ; GTK3: 'x-nautilus-
    desktop' is just an URI where the root is the path to the desktop
  - bzr3047-3048_Status-Notifier_Added_support_of_middle_click_and_scroll:
    Status-Notifier: IAS (ubuntu): added the support of the middle click ;
    Scroll signals were not catched
  - bzr3051_Logout_Added_support_of_Cinnamon.patch: logout: added support of
    Cinnamon
  - bzr3057_GMenu_new_apps_show_dialog_after_installation.patch: GMenu: new
    apps: show the dialog only after the end of the installation
  - bzr3065_Impulse_do_not_redraw_icon_when_not_needed.patch: Impulse: stop
    animations: do not redraw the icon if it's not needed (e.g. when
    disabling the applet)
  - bzr3067_AlsaMixer_support_cinnamon_settings.patch: AlsaMixer: added the
    support of cinnamon-settings
  - bzr3068_Clock_fixed_a_crash_when_configuring_when_not_enabled.patch:
    Clock: fixed a crash when configuring the applet if it's not activated
  - bzr3069_Indicator_Generic_no_need_to_hide_the_icon_before_removing_it:
    Indicator Generic: stop: no need to hide the icon before removing it
* debian/control: bumped Core versions

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 <stdlib.h>
 
21
#include <string.h>
 
22
#include <math.h>
 
23
 
 
24
#include "applet-struct.h"
 
25
#include "applet-item.h"
 
26
#include "applet-draw.h"
 
27
#include "applet-notifications.h"
 
28
 
 
29
//\___________ Define here the action to be taken when the user left-clicks on your icon or on its subdock or your desklet. The icon and the container that were clicked are available through the macros CD_APPLET_CLICKED_ICON and CD_APPLET_CLICKED_CONTAINER. CD_APPLET_CLICKED_ICON may be NULL if the user clicked in the container but out of icons.
 
30
 
 
31
static void _get_x_y (Icon *pIcon, GldiContainer *pContainer, int *x, int *y)
 
32
{
 
33
        if (pContainer->bIsHorizontal)
 
34
        {
 
35
                *x = pContainer->iWindowPositionX + pIcon->fDrawX + pIcon->fWidth * pIcon->fScale/2;
 
36
                *y = pContainer->iWindowPositionY + (pContainer->bDirectionUp ? 0 : pContainer->iHeight);
 
37
        }
 
38
        else
 
39
        {
 
40
                *x = pContainer->iWindowPositionY + (pContainer->bDirectionUp ? 0 : pContainer->iHeight);
 
41
                *y = pContainer->iWindowPositionX + pIcon->fDrawX + pIcon->fWidth * pIcon->fScale/2;
 
42
        }
 
43
        //g_print ("click position : %d;%d\n", *x, *y);
 
44
}
 
45
static inline gboolean _emit_click (CDStatusNotifierItem *pItem, Icon *pIcon, GldiContainer *pContainer, const gchar *cSignal)
 
46
{
 
47
        int x, y;
 
48
        _get_x_y (pIcon, pContainer, &x, &y);
 
49
        
 
50
        GError *erreur = NULL;
 
51
        dbus_g_proxy_call (pItem->pProxy, cSignal, &erreur,
 
52
                G_TYPE_INT, x,
 
53
                G_TYPE_INT, y,
 
54
                G_TYPE_INVALID,
 
55
                G_TYPE_INVALID);
 
56
        if (erreur != NULL)
 
57
        {
 
58
                //g_print ("method %s failed (%s)\n", cSignal, erreur->message);
 
59
                g_error_free (erreur);
 
60
                return FALSE;
 
61
        }
 
62
        return TRUE;
 
63
}
 
64
 
 
65
static inline CDStatusNotifierItem *_get_item (Icon *pClickedIcon, GldiContainer *pClickedContainer)
 
66
{
 
67
        CDStatusNotifierItem *pItem = NULL;
 
68
        if (myConfig.bCompactMode)
 
69
        {
 
70
                if (pClickedIcon == myIcon)  // clic sur la bonne icone.
 
71
                {
 
72
                        pItem = cd_satus_notifier_find_item_from_coord ();
 
73
                }
 
74
        }
 
75
        else
 
76
        {
 
77
                if ((myIcon->pSubDock != NULL && pClickedContainer == CAIRO_CONTAINER (myIcon->pSubDock)) ||
 
78
                        (myDesklet && pClickedContainer == myContainer))  // clic sur le bon container.
 
79
                {
 
80
                        pItem = cd_satus_notifier_get_item_from_icon (pClickedIcon);
 
81
                }
 
82
        }
 
83
        return pItem;
 
84
}
 
85
 
 
86
 
 
87
static gboolean _popup_menu (CDStatusNotifierItem *pItem, Icon *pIcon, GldiContainer *pContainer)
 
88
{
 
89
        gboolean r = FALSE;
 
90
        
 
91
        cd_satus_notifier_build_item_dbusmenu (pItem);
 
92
        if (pItem->pMenu != NULL)
 
93
        {
 
94
                gldi_menu_popup (GTK_WIDGET (pItem->pMenu));
 
95
                r = TRUE;
 
96
        }
 
97
 
 
98
        if (!r)  // no menu available, send the corresponding action
 
99
        {
 
100
                r = _emit_click (pItem, pIcon, pContainer, "ContextMenu");
 
101
        }
 
102
 
 
103
        if (!r)  // no luck, try to fallback on 'activate()'
 
104
        {
 
105
                r = _emit_click (pItem, pIcon, pContainer, "Activate");
 
106
        }
 
107
        
 
108
        return r;
 
109
}
 
110
 
 
111
CD_APPLET_ON_CLICK_BEGIN
 
112
        CDStatusNotifierItem *pItem = _get_item (CD_APPLET_CLICKED_ICON, CD_APPLET_CLICKED_CONTAINER);
 
113
        //g_print ("click on item '%s'\n", pItem?pItem->cService:"none");
 
114
        if (pItem != NULL)
 
115
        {
 
116
                // Ubuntu-like: show the menu on left click as the sole action (right-click = usual Cairo-Dock menu).
 
117
                if (myConfig.bMenuOnLeftClick || pItem->bItemIsMenu)  // if bItemIsMenu: "The item only support the context menu, the visualization should prefer sending ContextMenu() instead of Activate()"
 
118
                {
 
119
                        _popup_menu (pItem, CD_APPLET_CLICKED_ICON, CD_APPLET_CLICKED_CONTAINER);
 
120
                }
 
121
                else  // KDE-like: activate the item on left click, and show its menu on right-click.
 
122
                {
 
123
                        gboolean r;
 
124
                        r = _emit_click (pItem, CD_APPLET_CLICKED_ICON, CD_APPLET_CLICKED_CONTAINER, "Activate");
 
125
                        
 
126
                        if (!r)
 
127
                        {
 
128
                                if (pItem->cId != NULL)
 
129
                                {
 
130
                                        /// TODO: try to get the icon in the taskbar, because launch the command doesn't raise the window if it was already visible (but it does pop up it if it was hidden, usually).
 
131
                                        cairo_dock_launch_command (pItem->cId);  // try to launch the application because generally this click shows its item's window.
 
132
                                }
 
133
                        }
 
134
                }
 
135
        }
 
136
CD_APPLET_ON_CLICK_END
 
137
 
 
138
 
 
139
CD_APPLET_ON_MIDDLE_CLICK_BEGIN
 
140
        CDStatusNotifierItem *pItem = _get_item (CD_APPLET_CLICKED_ICON, CD_APPLET_CLICKED_CONTAINER);
 
141
        if (pItem != NULL)
 
142
        {
 
143
                _emit_click (pItem, CD_APPLET_CLICKED_ICON, CD_APPLET_CLICKED_CONTAINER, "SecondaryActivate");
 
144
        }
 
145
CD_APPLET_ON_MIDDLE_CLICK_END
 
146
 
 
147
 
 
148
CD_APPLET_ON_SCROLL_BEGIN
 
149
        CDStatusNotifierItem *pItem = _get_item (CD_APPLET_CLICKED_ICON, CD_APPLET_CLICKED_CONTAINER);
 
150
        if (pItem != NULL)
 
151
        {
 
152
                GError *erreur = NULL;
 
153
                dbus_g_proxy_call (pItem->pProxy, "Scroll", &erreur,
 
154
                        G_TYPE_INT, CD_APPLET_SCROLL_UP ? +1 : -1,
 
155
                        G_TYPE_STRING, "vertical",
 
156
                        G_TYPE_INVALID,
 
157
                        G_TYPE_INVALID);
 
158
                if (erreur != NULL)
 
159
                {
 
160
                        //g_print ("method %s failed (%s)\n", "Scroll", erreur->message);
 
161
                        g_error_free (erreur);
 
162
                }
 
163
        }
 
164
CD_APPLET_ON_SCROLL_END
 
165
 
 
166
 
 
167
//\___________ Define here the entries you want to add to the menu when the user right-clicks on your icon or on its subdock or your desklet. The icon and the container that were clicked are available through the macros CD_APPLET_CLICKED_ICON and CD_APPLET_CLICKED_CONTAINER. CD_APPLET_CLICKED_ICON may be NULL if the user clicked in the container but out of icons. The menu where you can add your entries is available throught the macro CD_APPLET_MY_MENU; you can add sub-menu to it if you want.
 
168
/*CD_APPLET_ON_BUILD_MENU_BEGIN
 
169
 
 
170
CD_APPLET_ON_BUILD_MENU_END*/
 
171
 
 
172
 
 
173
gboolean cd_status_notifier_on_right_click (GldiModuleInstance *myApplet, Icon *pClickedIcon, GldiContainer *pClickedContainer, GtkWidget *pAppletMenu, gboolean *bDiscardMenu)
 
174
{
 
175
        if (pClickedIcon == NULL || myConfig.bMenuOnLeftClick)
 
176
                return GLDI_NOTIFICATION_LET_PASS;
 
177
        
 
178
        CD_APPLET_ENTER;
 
179
        CDStatusNotifierItem *pItem = _get_item (pClickedIcon, pClickedContainer);
 
180
        if (pItem != NULL)
 
181
        {
 
182
                _popup_menu (pItem, pClickedIcon, pClickedContainer);
 
183
 
 
184
                *bDiscardMenu = TRUE;
 
185
                CD_APPLET_LEAVE (GLDI_NOTIFICATION_INTERCEPT);
 
186
        }
 
187
        CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS);
 
188
}
 
189
 
 
190
 
 
191
/*static gboolean _popup_tooltip (Icon *pIcon)
 
192
{
 
193
        CDStatusNotifierItem *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
194
        if (pItemData != NULL && pItemData->pToolTip != NULL)
 
195
        {
 
196
                myDialogsParam.dialogTextDescription.bUseMarkup = TRUE;
 
197
                //g_print ("pItemData->pToolTip->cMessage : %s\n", pItemData->pToolTip->cMessage);
 
198
                gchar *cText = g_strdup_printf ("<b>%s</b>\n%s", pItemData->pToolTip->cTitle, pItemData->pToolTip->cMessage);
 
199
                gchar *cIconPath = NULL;
 
200
                if (pItemData->pToolTip->cIconName)
 
201
                {
 
202
                        cIconPath = cairo_dock_search_icon_s_path (pItemData->pToolTip->cIconName, cairo_dock_search_icon_size (GTK_ICON_SIZE_DND)); // dialog
 
203
                }
 
204
                
 
205
                gldi_dialog_show_temporary_with_icon (cText, pIcon, CAIRO_CONTAINER (myIcon->pSubDock), 3000, cIconPath ? cIconPath : "same icon");
 
206
                g_free (cText);
 
207
                myDialogsParam.dialogTextDescription.bUseMarkup = FALSE;
 
208
                pItemData->iSidPopupTooltip = 0;
 
209
        }
 
210
        return FALSE;
 
211
}*/
 
212
gboolean cd_status_notifier_on_enter_icon (GldiModuleInstance *myApplet, Icon *pIcon, CairoDock *pDock, gboolean *bStartAnimation)
 
213
{
 
214
        if (pDock == myIcon->pSubDock && myIcon->pSubDock != NULL)
 
215
        {
 
216
                /*Icon *icon = NULL;
 
217
                GList *ic;
 
218
                for (ic = myData.pIcons; ic != NULL; ic = ic->next)
 
219
                {
 
220
                        icon = ic->data;
 
221
                        CDStatusNotifierItem *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
222
                        if (pItemData && pItemData->iSidPopupTooltip != 0)
 
223
                        {
 
224
                                g_source_remove (pItemData->iSidPopupTooltip);
 
225
                                pItemData->iSidPopupTooltip = 0;
 
226
                        }
 
227
                        gldi_dialogs_remove_on_icon (icon);
 
228
                }
 
229
                
 
230
                if (pIcon)
 
231
                {
 
232
                        CDStatusNotifierItem *pItemData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
 
233
                        pItemData->iSidPopupTooltip = g_timeout_add (600, (GSourceFunc) _popup_tooltip, pIcon);
 
234
                }*/
 
235
        }
 
236
        return GLDI_NOTIFICATION_LET_PASS;
 
237
}
 
238
 
 
239
 
 
240
 
 
241
gboolean on_mouse_moved (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bStartAnimation)
 
242
{
 
243
        CD_APPLET_ENTER;
 
244
        if (! myIcon->bPointed || ! pContainer->bInside)
 
245
                CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS);
 
246
        
 
247
        CDStatusNotifierItem *pItem = cd_satus_notifier_find_item_from_coord ();
 
248
        
 
249
        if (pItem != myData.pCurrentlyHoveredItem)
 
250
        {
 
251
                myData.pCurrentlyHoveredItem = pItem;
 
252
                myData.fDesktopNameAlpha = 0.;
 
253
                if (pItem == NULL)
 
254
                        CD_APPLET_SET_NAME_FOR_MY_ICON (NULL);
 
255
                else
 
256
                {
 
257
                        GString *sTitle = g_string_new ("");
 
258
                        if (pItem->cTitle && *pItem->cTitle != '\0')
 
259
                        {
 
260
                                gunichar wc = g_utf8_get_char (pItem->cTitle);
 
261
                                g_string_append_unichar (sTitle, g_unichar_toupper (wc));  // force the first char to upper
 
262
                                g_string_append (sTitle, g_utf8_next_char (pItem->cTitle));
 
263
                        }
 
264
                        if (pItem->cLabel && *pItem->cLabel != '\0')
 
265
                                g_string_append_printf (sTitle, "%s%s", sTitle->len == 0 ? "" : " | ", pItem->cLabel);
 
266
                        if (pItem->cAccessibleDesc && *pItem->cAccessibleDesc != '\0')
 
267
                                g_string_append_printf (sTitle, "%s%s", sTitle->len == 0 ? "" : " | ", pItem->cAccessibleDesc);
 
268
                        if (sTitle->len == 0)  // don't display an empty label
 
269
                        {
 
270
                                /*
 
271
                                 * Let's display the ID if we really have nothing, just to avoid
 
272
                                 * having a gap (no label), inconsistency (only on some items),
 
273
                                 * and an item that you can't guess until you click on it.
 
274
                                 * This is a workaround for applications that don't provide a
 
275
                                 * label yet, which should hopefully become rare!
 
276
                                 * Since the ID is sometimes too ugly (e.g: dropbox-xxxx,
 
277
                                 * emesene-xxxxxxxxx, etc.), we cut the string.
 
278
                                 */
 
279
                                gchar *cName = cairo_dock_cut_string (pItem->cId, 12);
 
280
                                CD_APPLET_SET_NAME_FOR_MY_ICON (cName);
 
281
                                g_free (cName);
 
282
                        }
 
283
                        else
 
284
                                CD_APPLET_SET_NAME_FOR_MY_ICON (sTitle->str);
 
285
                        g_string_free (sTitle, TRUE);
 
286
                }
 
287
                if (myDock)
 
288
                        CAIRO_DOCK_REDRAW_MY_CONTAINER;
 
289
                else
 
290
                        *bStartAnimation = TRUE;
 
291
        }
 
292
        CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS);
 
293
}
 
294
 
 
295
gboolean on_update_desklet (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bContinueAnimation)
 
296
{
 
297
        CD_APPLET_ENTER;
 
298
        if (! myIcon->bPointed || ! pContainer->bInside)
 
299
        {
 
300
                myData.fDesktopNameAlpha -= .07;
 
301
                if (myData.fDesktopNameAlpha < .01)
 
302
                        myData.fDesktopNameAlpha = 0;
 
303
                if (myData.fDesktopNameAlpha != 0)
 
304
                        *bContinueAnimation = TRUE;
 
305
        }
 
306
        else
 
307
        {
 
308
                myData.fDesktopNameAlpha += .07;
 
309
                if (myData.fDesktopNameAlpha > .99)
 
310
                        myData.fDesktopNameAlpha = 1;
 
311
                if (myData.fDesktopNameAlpha != 1)
 
312
                        *bContinueAnimation = TRUE;
 
313
        }
 
314
        CAIRO_DOCK_REDRAW_MY_CONTAINER;
 
315
        CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS);
 
316
}
 
317
 
 
318
gboolean on_render_desklet (GldiModuleInstance *myApplet, GldiContainer *pContainer, cairo_t *pCairoContext)
 
319
{
 
320
        CD_APPLET_ENTER;
 
321
        int x, y;  // text center (middle of the icon).
 
322
        x = myIcon->fDrawX + myIcon->fWidth * myIcon->fScale / 2;
 
323
        y = myIcon->fDrawY + myIcon->fHeight * myIcon->fScale / 2;
 
324
        if (x - myIcon->label.iWidth/2 < 0)
 
325
        {
 
326
                x -= myIcon->label.iWidth/2;
 
327
        }
 
328
        if (pCairoContext != NULL)
 
329
        {
 
330
                if (myIcon->label.pSurface != NULL)
 
331
                {
 
332
                        /**cairo_save (pCairoContext);
 
333
                        cairo_translate (pCairoContext, x, y);
 
334
                        cairo_set_source_surface (pCairoContext, myIcon->pTextBuffer, - myIcon->iTextWidth/2, - myIcon->iTextHeight/2);
 
335
                        cairo_paint_with_alpha (pCairoContext, myData.fDesktopNameAlpha);
 
336
                        cairo_restore (pCairoContext);*/
 
337
                        cairo_dock_apply_image_buffer_surface_with_offset (&myIcon->label, pCairoContext,
 
338
                                - myIcon->label.iWidth/2, - myIcon->label.iHeight/2, myData.fDesktopNameAlpha);
 
339
                }
 
340
        }
 
341
        else
 
342
        {
 
343
                if (myIcon->label.iTexture != 0)
 
344
                {
 
345
                        glPushMatrix ();
 
346
                        glTranslatef (-myContainer->iWidth/2, -myContainer->iHeight/2, -myContainer->iHeight*(sqrt(3)/2));
 
347
                        /**glTranslatef (x - ((myIcon->iTextWidth & 1) ? 0.5 : 0.),
 
348
                                y - ((myIcon->iTextHeight & 1) ? 0.5 : 0.),
 
349
                                0);
 
350
                        cairo_dock_draw_texture_with_alpha (myIcon->iLabelTexture, myIcon->iTextWidth, myIcon->iTextHeight, myData.fDesktopNameAlpha);*/
 
351
                        _cairo_dock_enable_texture ();
 
352
                        _cairo_dock_set_blend_alpha ();
 
353
                        _cairo_dock_set_alpha (myData.fDesktopNameAlpha);
 
354
                        cairo_dock_apply_image_buffer_texture_with_offset (&myIcon->label,
 
355
                                x - ((myIcon->label.iWidth & 1) ? 0.5 : 0.),
 
356
                                y - ((myIcon->label.iHeight & 1) ? 0.5 : 0.));
 
357
                        _cairo_dock_disable_texture ();
 
358
                        glPopMatrix ();
 
359
                }
 
360
        }
 
361
        CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS);
 
362
}
 
363
 
 
364
gboolean on_leave_desklet (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bStartAnimation)
 
365
{
 
366
        *bStartAnimation = TRUE;
 
367
        myData.pCurrentlyHoveredItem = NULL;
 
368
        return GLDI_NOTIFICATION_LET_PASS;
 
369
}