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/>.
22
#include "applet-config.h"
23
#include "applet-notifications.h"
24
#include "applet-app.h"
25
#include "applet-draw.h"
26
#include "applet-struct.h"
27
#include "applet-init.h"
30
CD_APPLET_DEFINE_BEGIN (N_("Global Menu"),
32
CAIRO_DOCK_CATEGORY_APPLET_DESKTOP,
33
N_("This applet allows you to control the current active window:\n"
34
" close, minimize, maximize, and display the application menu."
35
"To display the menu, applications have to support this feature, which is the case on Ubuntu by default.\n"
36
"You can bind a shortkey to this action."),
38
CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE
39
CD_APPLET_ALLOW_EMPTY_TITLE
42
static gboolean _reversed_buttons_order (void)
43
{ // TRUE: on the left (close, min, max) || FALSE: on the right (min, max, close)
44
if (myConfig.iButtonsOrder == CD_GM_BUTTON_ORDER_AUTO
45
&& ((myDock && (int) myIcon->fXAtRest < (g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] / 2))
46
|| (myDesklet && myDesklet->container.iWindowPositionX < (g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] / 2))))
48
return (myConfig.iButtonsOrder == CD_GM_BUTTON_ORDER_LEFT);
51
//\___________ Here is where you initiate your applet. myConfig is already set at this point, and also myIcon, myContainer, myDock, myDesklet (and myDrawContext if you're in dock mode). The macro CD_APPLET_MY_CONF_FILE and CD_APPLET_MY_KEY_FILE can give you access to the applet's conf-file and its corresponding key-file (also available during reload). If you're in desklet mode, myDrawContext is still NULL, and myIcon's buffers has not been filled, because you may not need them then (idem when reloading).
55
CD_APPLET_SET_DESKLET_RENDERER ("Simple"); // set a desklet renderer.
58
cairo_dock_register_notification_on_object (&myDesktopMgr,
59
NOTIFICATION_WINDOW_ACTIVATED,
60
(CairoDockNotificationFunc) cd_app_menu_on_active_window_changed,
61
CAIRO_DOCK_RUN_AFTER, myApplet);
62
cairo_dock_register_notification_on_object (&myTaskbarMgr,
63
NOTIFICATION_APPLI_STATE_CHANGED,
64
(CairoDockNotificationFunc) cd_app_menu_on_state_changed,
65
CAIRO_DOCK_RUN_AFTER, myApplet);
66
cairo_dock_register_notification_on_object (&myTaskbarMgr,
67
NOTIFICATION_APPLI_NAME_CHANGED,
68
(CairoDockNotificationFunc) cd_app_menu_on_name_changed,
69
CAIRO_DOCK_RUN_AFTER, myApplet);
70
cairo_dock_register_notification_on_object (&myTaskbarMgr,
71
NOTIFICATION_APPLI_CREATED,
72
(CairoDockNotificationFunc) cd_app_menu_on_new_appli,
73
CAIRO_DOCK_RUN_AFTER, myApplet);
74
/**cairo_dock_register_notification_on_object (&myDesktopMgr,
75
NOTIFICATION_WINDOW_PROPERTY_CHANGED,
76
(CairoDockNotificationFunc) cd_app_menu_on_property_changed,
77
CAIRO_DOCK_RUN_AFTER, myApplet);*/
79
cairo_dock_register_notification_on_object (myContainer,
80
NOTIFICATION_MOUSE_MOVED,
81
(CairoDockNotificationFunc) on_mouse_moved,
82
CAIRO_DOCK_RUN_AFTER, myApplet);
83
cairo_dock_register_notification_on_object (myContainer,
84
NOTIFICATION_UPDATE_SLOW,
85
(CairoDockNotificationFunc) cd_app_menu_on_update_container,
86
CAIRO_DOCK_RUN_AFTER, myApplet);
89
myData.iNbButtons = myConfig.bDisplayControls * 3 + 1; // we display the icon even if we don't provide the menu.
92
if (myConfig.bDisplayControls) // no animation on mouse hover if the buttons are displayed, it's hard to click
94
CD_APPLET_SET_STATIC_ICON;
95
myData.bReversedButtonsOrder = FALSE; /// _reversed_buttons_order (); => TODO? check if the position of the icon has changed. => the position of the icon seems to not be correct if we call this function here... we can check if something has changed with CD_APPLET_RELOAD but the order doesn't change if the icon has been moved in the same dock (it works if the container has changed). Do we have to register to this notifications? => NOTIFICATION_ICON_MOVED
99
CD_APPLET_REGISTER_FOR_CLICK_EVENT;
100
CD_APPLET_REGISTER_FOR_MIDDLE_CLICK_EVENT;
101
CD_APPLET_REGISTER_FOR_DOUBLE_CLICK_EVENT;
102
CD_APPLET_REGISTER_FOR_BUILD_MENU_EVENT;
103
CD_APPLET_REGISTER_FOR_SCROLL_EVENT;
106
if (myConfig.bDisplayMenu)
107
myData.pKeyBinding = CD_APPLET_BIND_KEY (myConfig.cShortkey,
108
D_("Show/hide the current application menu"),
109
"Configuration", "shortkey",
110
(CDBindkeyHandler) cd_app_menu_on_keybinding_pull);
114
//\___________ Here is where you stop your applet. myConfig and myData are still valid, but will be reseted to 0 at the end of the function. In the end, your applet will go back to its original state, as if it had never been activated.
116
cairo_dock_remove_notification_func_on_object (&myDesktopMgr,
117
NOTIFICATION_WINDOW_ACTIVATED,
118
(CairoDockNotificationFunc) cd_app_menu_on_active_window_changed, myApplet);
119
/**cairo_dock_remove_notification_func_on_object (&myDesktopMgr,
120
NOTIFICATION_WINDOW_PROPERTY_CHANGED,
121
(CairoDockNotificationFunc) cd_app_menu_on_property_changed, myApplet);*/
122
cairo_dock_remove_notification_func_on_object (&myTaskbarMgr,
123
NOTIFICATION_APPLI_STATE_CHANGED,
124
(CairoDockNotificationFunc) cd_app_menu_on_state_changed, myApplet);
125
cairo_dock_remove_notification_func_on_object (&myTaskbarMgr,
126
NOTIFICATION_APPLI_NAME_CHANGED,
127
(CairoDockNotificationFunc) cd_app_menu_on_name_changed, myApplet);
128
cairo_dock_remove_notification_func_on_object (&myTaskbarMgr,
129
NOTIFICATION_APPLI_CREATED,
130
(CairoDockNotificationFunc) cd_app_menu_on_new_appli, myApplet);
132
cairo_dock_remove_notification_func_on_object (myContainer,
133
NOTIFICATION_MOUSE_MOVED,
134
(CairoDockNotificationFunc) on_mouse_moved, myApplet);
135
cairo_dock_remove_notification_func_on_object (myContainer,
136
NOTIFICATION_UPDATE_SLOW,
137
(CairoDockNotificationFunc) cd_app_menu_on_update_container, myApplet);
142
CD_APPLET_UNREGISTER_FOR_CLICK_EVENT;
143
CD_APPLET_UNREGISTER_FOR_DOUBLE_CLICK_EVENT;
144
CD_APPLET_UNREGISTER_FOR_MIDDLE_CLICK_EVENT;
145
CD_APPLET_UNREGISTER_FOR_BUILD_MENU_EVENT;
146
CD_APPLET_UNREGISTER_FOR_SCROLL_EVENT;
149
if (myConfig.bDisplayMenu)
150
cd_keybinder_unbind (myData.pKeyBinding);
154
//\___________ The reload occurs in 2 occasions : when the user changes the applet's config, and when the user reload the cairo-dock's config or modify the desklet's size. The macro CD_APPLET_MY_CONFIG_CHANGED can tell you this. myConfig has already been reloaded at this point if you're in the first case, myData is untouched. You also have the macro CD_APPLET_MY_CONTAINER_TYPE_CHANGED that can tell you if you switched from dock/desklet to desklet/dock mode.
155
CD_APPLET_RELOAD_BEGIN
156
// if they are loaded, reload the controls icons.
157
cd_app_menu_load_button_images ();
158
cd_app_menu_default_image ();
160
if (CD_APPLET_MY_CONFIG_CHANGED)
162
if (myDesklet && CD_APPLET_MY_CONTAINER_TYPE_CHANGED) // we are now in a desklet, set a renderer.
164
CD_APPLET_SET_DESKLET_RENDERER ("Simple");
167
if (CD_APPLET_MY_OLD_CONTAINER != myContainer)
169
cairo_dock_remove_notification_func_on_object (CD_APPLET_MY_OLD_CONTAINER,
170
NOTIFICATION_MOUSE_MOVED,
171
(CairoDockNotificationFunc) on_mouse_moved, myApplet);
172
cairo_dock_remove_notification_func_on_object (CD_APPLET_MY_OLD_CONTAINER,
173
NOTIFICATION_UPDATE_SLOW,
174
(CairoDockNotificationFunc) cd_app_menu_on_update_container, myApplet);
176
cairo_dock_register_notification_on_object (myContainer,
177
NOTIFICATION_MOUSE_MOVED,
178
(CairoDockNotificationFunc) on_mouse_moved,
179
CAIRO_DOCK_RUN_AFTER, myApplet);
180
cairo_dock_register_notification_on_object (myContainer,
181
NOTIFICATION_UPDATE_SLOW,
182
(CairoDockNotificationFunc) cd_app_menu_on_update_container,
183
CAIRO_DOCK_RUN_AFTER, myApplet);
187
cd_app_menu_set_windows_borders (!myConfig.bDisplayControls);
190
if (myConfig.bDisplayMenu && !myData.pProxyRegistrar)
191
cd_app_detect_registrar ();
192
else if (! myConfig.bDisplayMenu) // even if myData.pProxyRegistrar is NULL, we have to cancel the detection
193
cd_app_disconnect_from_registrar ();
195
// to update any param that could have changed, simply re-set the current window.
196
myData.iNbButtons = myConfig.bDisplayControls * 3 + 1;
197
myData.iAnimIterMin = myData.iAnimIterMax = myData.iAnimIterClose = 0;
198
myData.bButtonAnimating = FALSE;
199
Window iActiveWindow = myData.iCurrentWindow;
200
myData.iCurrentWindow = 0;
201
cd_app_menu_set_current_window (iActiveWindow);
204
if (myConfig.bDisplayMenu)
206
if (myData.pKeyBinding)
207
cd_keybinder_rebind (myData.pKeyBinding, myConfig.cShortkey, NULL);
209
myData.pKeyBinding = CD_APPLET_BIND_KEY (myConfig.cShortkey,
210
D_("Show/hide the current application menu"),
211
"Configuration", "shortkey",
212
(CDBindkeyHandler) cd_app_menu_on_keybinding_pull);
214
else if (myData.pKeyBinding)
216
cd_keybinder_unbind (myData.pKeyBinding);
219
cairo_dock_set_icon_static (myIcon, myConfig.bDisplayControls);
222
if (myConfig.bDisplayControls)
224
myData.bReversedButtonsOrder = _reversed_buttons_order ();
225
cd_app_menu_resize ();