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
23 #include "applet-struct.h"
24 #include "applet-composite.h"
25
26 static void (*s_activate_composite) (gboolean) = NULL;
27
28 /////////////////////
29 /// WM Composite ///
30 /////////////////////
31
_set_metacity_composite(gboolean bActive)32 static void _set_metacity_composite (gboolean bActive)
33 {
34 int r;
35 if (bActive)
36 r = system ("if test -n \"`dconf read /org/gnome/metacity/compositing-manager`\"; then dconf write /org/gnome/metacity/compositing-manager true; metacity --replace& else gconftool-2 -s '/apps/metacity/general/compositing_manager' --type bool true; fi"); // metacity's new feature : now uses Dconf and crashes after activating the composite
37 else
38 r = system ("if test -n \"`dconf read /org/gnome/metacity/compositing-manager`\"; then dconf write /org/gnome/metacity/compositing-manager false; metacity --replace& else gconftool-2 -s '/apps/metacity/general/compositing_manager' --type bool false; fi");
39 if (r < 0)
40 cd_warning ("Not able to launch this command: gconftool-2");
41 }
42
_set_xfwm_composite(gboolean bActive)43 static void _set_xfwm_composite (gboolean bActive)
44 {
45 int r;
46 if (bActive)
47 r = system ("xfconf-query -c xfwm4 -p '/general/use_compositing' -t 'bool' -s 'true'");
48 else
49 r = system ("xfconf-query -c xfwm4 -p '/general/use_compositing' -t 'bool' -s 'false'");
50 if (r < 0)
51 cd_warning ("Not able to launch this command: gconftool-2");
52 }
53
_set_kwin_composite(gboolean bActive)54 static void _set_kwin_composite (gboolean bActive)
55 {
56 int r;
57 if (bActive)
58 r = system ("[ \"$(qdbus org.kde.kwin /KWin compositingActive)\" == \"false\" ] && qdbus org.kde.kwin /KWin toggleCompositing"); // not active, so activating
59 else
60 r = system ("[ \"$(qdbus org.kde.kwin /KWin compositingActive)\" == \"true\" ] && qdbus org.kde.kwin /KWin toggleCompositing"); // active, so deactivating
61 if (r < 0)
62 cd_warning ("Not able to launch this command: gconftool-2");
63 }
64
65 ///////////////////////
66 /// Welcome message ///
67 ///////////////////////
68
cd_help_show_welcome_message(void)69 static void cd_help_show_welcome_message (void)
70 {
71 gldi_dialog_show (D_("Welcome in Cairo-Dock !\n"
72 "This applet is here to help you start using the dock; just click on it.\n"
73 "If you have any question/request/remark, please pay us a visit at http://glx-dock.org.\n"
74 "Hope you will enjoy this soft !\n"
75 " (you can now click on this dialog to close it)"),
76 myIcon, myContainer,
77 0,
78 "same icon",
79 NULL, NULL, NULL, NULL);
80 myData.bFirstLaunch = FALSE;
81 }
82
83 ////////////////////////
84 /// Composite dialog ///
85 ////////////////////////
86
_cancel_wm_composite(void)87 static inline void _cancel_wm_composite (void)
88 {
89 s_activate_composite (FALSE);
90 }
_accept_wm_composite(int iClickedButton,G_GNUC_UNUSED GtkWidget * pInteractiveWidget,gpointer data,G_GNUC_UNUSED CairoDialog * pDialog)91 static void _accept_wm_composite (int iClickedButton, G_GNUC_UNUSED GtkWidget *pInteractiveWidget, gpointer data, G_GNUC_UNUSED CairoDialog *pDialog)
92 {
93 cd_debug ("%s (%d)", __func__, iClickedButton);
94 if (iClickedButton == 1 || iClickedButton == -2) // clic explicite sur "cancel", ou Echap ou auto-delete.
95 {
96 _cancel_wm_composite ();
97 }
98 gboolean *bAccepted = data;
99 *bAccepted = TRUE; // l'utilisateur a valide son choix.
100 }
_on_free_wm_dialog(gpointer data)101 static void _on_free_wm_dialog (gpointer data)
102 {
103 gboolean *bAccepted = data;
104 cd_debug ("%s (%d)", __func__, *bAccepted);
105 if (! *bAccepted) // le dialogue s'est detruit sans que l'utilisateur n'ait valide la question => on annule tout.
106 {
107 _cancel_wm_composite ();
108 }
109 g_free (data);
110
111 if (myData.bFirstLaunch)
112 {
113 cd_help_show_welcome_message ();
114 }
115 }
116
_toggle_remember_choice(GtkCheckButton * pButton,GtkWidget * pDialog)117 static void _toggle_remember_choice (GtkCheckButton *pButton, GtkWidget *pDialog)
118 {
119 g_object_set_data (G_OBJECT (pDialog), "remember", GINT_TO_POINTER (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pButton))));
120 }
121
_on_free_info_dialog(G_GNUC_UNUSED gpointer data)122 static void _on_free_info_dialog (G_GNUC_UNUSED gpointer data)
123 {
124 if (myData.bFirstLaunch)
125 {
126 cd_help_show_welcome_message ();
127 }
128 }
129
130 ///////////////////////
131 /// Check composite ///
132 ///////////////////////
133
cd_help_enable_composite(void)134 void cd_help_enable_composite (void)
135 {
136 // find the current WM.
137 s_activate_composite = NULL;
138 gchar *cPsef = cairo_dock_launch_command_sync ("pgrep metacity"); // 'ps | grep' ne marche pas, il faut le lancer dans un script :-/
139 cd_debug ("cPsef: '%s'", cPsef);
140 if (cPsef != NULL && *cPsef != '\0')
141 {
142 s_activate_composite = _set_metacity_composite;
143 }
144 else
145 {
146 cPsef = cairo_dock_launch_command_sync ("pgrep xfwm");
147 if (cPsef != NULL && *cPsef != '\0')
148 {
149 s_activate_composite = _set_xfwm_composite;
150 }
151 else
152 {
153 cPsef = cairo_dock_launch_command_sync ("pgrep kwin");
154 if (cPsef != NULL && *cPsef != '\0')
155 {
156 s_activate_composite = _set_kwin_composite;
157 }
158 }
159 }
160
161 // if the WM can handle the composite, ask the user if he wants to enable it.
162 if (s_activate_composite != NULL) // the WM can activate the composite.
163 {
164 GtkWidget *pAskBox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
165 GtkWidget *label = gtk_label_new (D_("Don't ask me any more"));
166 gldi_dialog_set_widget_text_color (label);
167 GtkWidget *pCheckBox = gtk_check_button_new ();
168 gtk_box_pack_end (GTK_BOX (pAskBox), pCheckBox, FALSE, FALSE, 0);
169 gtk_box_pack_end (GTK_BOX (pAskBox), label, FALSE, FALSE, 0);
170 g_signal_connect (G_OBJECT (pCheckBox), "toggled", G_CALLBACK(_toggle_remember_choice), pAskBox);
171 int iClickedButton = gldi_dialog_show_and_wait (D_("To remove the black rectangle around the dock, you need to activate a composite manager.\nDo you want to activate it now?"), myIcon, myContainer, NULL, pAskBox);
172
173 gboolean bRememberChoice = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (pCheckBox));
174 gtk_widget_destroy (pAskBox); // le widget survit a un dialogue bloquant.
175 if (bRememberChoice) // if not ticked, we'll check the composite on the next startup, and if it's ok, we'll not check it any more.
176 {
177 myData.bTestComposite = FALSE;
178 }
179 if (iClickedButton == 0 || iClickedButton == -1) // ok or Enter.
180 {
181 s_activate_composite (TRUE);
182 gldi_dialog_show (D_("Do you want to keep this setting?\nIn 15 seconds, the previous setting will be restored."),
183 myIcon, myContainer,
184 15e3,
185 "same icon",
186 NULL,
187 (CairoDockActionOnAnswerFunc) _accept_wm_composite,
188 g_new0 (gboolean, 1),
189 (GFreeFunc)_on_free_wm_dialog);
190 }
191 else if (myData.bFirstLaunch)
192 {
193 cd_help_show_welcome_message ();
194 }
195 }
196 else // just notify him about the problem and its solution.
197 {
198 gldi_dialog_show (D_("To remove the black rectangle around the dock, you will need to activate a composite manager.\nFor instance, this can be done by activating desktop effects, launching Compiz, or activating the composition in Metacity.\nIf your machine can't support composition, Cairo-Dock can emulate it. This option is in the 'System' module of the configuration, at the bottom of the page."),
199 myIcon, myContainer,
200 0,
201 "same icon",
202 NULL,
203 NULL,
204 NULL,
205 (GFreeFunc)_on_free_info_dialog);
206 }
207 g_free (cPsef);
208 }
209
cd_help_check_composite(G_GNUC_UNUSED gpointer data)210 static gboolean cd_help_check_composite (G_GNUC_UNUSED gpointer data)
211 {
212 GdkScreen *pScreen = gdk_screen_get_default ();
213 if (! gdk_screen_is_composited (pScreen)) // no composite yet.
214 {
215 cd_debug ("no composite (%d)", myData.iNbTestComposite);
216 myData.iNbTestComposite ++;
217 if (myData.iNbTestComposite < 4) // check during 4 seconds.
218 return TRUE;
219
220 cd_help_enable_composite ();
221 }
222 else // composite is active, but we don't remember this parameter, since it could change if another session is used one day.
223 {
224 if (myData.bFirstLaunch)
225 {
226 cd_help_show_welcome_message ();
227 }
228 }
229
230 // remember if we don't need to check the composite any more.
231 if (! myData.bTestComposite)
232 {
233 gchar *cConfFilePath = g_strdup_printf ("%s/.help", g_cCairoDockDataDir);
234 cairo_dock_update_conf_file (cConfFilePath,
235 G_TYPE_BOOLEAN, "Launch", "test composite", myData.bTestComposite,
236 G_TYPE_INVALID);
237 g_free (cConfFilePath);
238 }
239 myData.iSidTestComposite = 0;
240 return FALSE;
241 }
242
cd_help_get_params(G_GNUC_UNUSED gpointer data)243 gboolean cd_help_get_params (G_GNUC_UNUSED gpointer data)
244 {
245 // read our file.
246 gchar *cConfFilePath = g_strdup_printf ("%s/.help", g_cCairoDockDataDir);
247 if (g_file_test (cConfFilePath, G_FILE_TEST_EXISTS)) // file already exists, get the latest state.
248 {
249 GKeyFile *pKeyFile = cairo_dock_open_key_file (cConfFilePath);
250 if (pKeyFile != NULL)
251 {
252 myData.iLastTipGroup = g_key_file_get_integer (pKeyFile, "Last Tip", "group", NULL);
253 myData.iLastTipKey = g_key_file_get_integer (pKeyFile, "Last Tip", "key", NULL);
254 myData.bTestComposite = g_key_file_get_boolean (pKeyFile, "Launch", "test composite", NULL);
255
256 g_key_file_free (pKeyFile);
257 }
258 }
259 else // no file, means it's the first time we are launched.
260 {
261 myData.bFirstLaunch = TRUE;
262 myData.bTestComposite = TRUE;
263
264 // create the file with all the entries
265 cairo_dock_update_conf_file (cConfFilePath,
266 G_TYPE_BOOLEAN, "Launch", "test composite", myData.bTestComposite,
267 G_TYPE_INT, "Last Tip", "group", myData.iLastTipGroup,
268 G_TYPE_INT, "Last Tip", "key", myData.iLastTipKey,
269 G_TYPE_INVALID);
270 }
271
272 // test the composite in a few seconds (the Composite Manager may not be active yet).
273 if (myData.bTestComposite/** && ! myContainersParam.bUseFakeTransparency*/)
274 {
275 myData.iSidTestComposite = g_timeout_add_seconds (2, cd_help_check_composite, NULL);
276 }
277 else if (myData.bFirstLaunch)
278 {
279 cd_help_show_welcome_message ();
280 }
281
282 g_free (cConfFilePath);
283 myData.iSidGetParams = 0;
284 return FALSE;
285 }
286