1
/* $Id: xfce-tray-plugin.c 29188 2009-01-12 17:08:56Z nick $ */
3
* Copyright (c) 2007 Nick Schermer <nick@xfce.org>
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License as published by the Free
7
* Software Foundation; either version 2 of the License, or (at your option)
10
* This program is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
* You should have received a copy of the GNU General Public License along with
16
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17
* Place, Suite 330, Boston, MA 02111-1307 USA
24
#define SMALL_PANEL_SIZE (26)
27
#include <libxfce4util/libxfce4util.h>
28
#include <libxfce4panel/xfce-panel-plugin.h>
29
#include <libxfce4panel/xfce-panel-macros.h>
31
#include "xfce-tray-manager.h"
32
#include "xfce-tray-widget.h"
33
#include "xfce-tray-plugin.h"
34
#include "xfce-tray-dialogs.h"
39
static void xfce_tray_plugin_message (GtkMessageType type,
41
const gchar *message);
42
static gboolean xfce_tray_plugin_check (GdkScreen *screen);
43
static void xfce_tray_plugin_update_position (XfceTrayPlugin *plugin);
44
static XfceTrayPlugin *xfce_tray_plugin_new (XfcePanelPlugin *panel_plugin);
45
static void xfce_tray_plugin_screen_position_changed (XfceTrayPlugin *plugin,
46
XfceScreenPosition position);
47
static void xfce_tray_plugin_orientation_changed (XfceTrayPlugin *plugin,
48
GtkOrientation orientation);
49
static gboolean xfce_tray_plugin_size_changed (XfceTrayPlugin *plugin,
51
static void xfce_tray_plugin_read (XfceTrayPlugin *plugin);
52
static void xfce_tray_plugin_write (XfceTrayPlugin *plugin);
53
static void xfce_tray_plugin_free (XfceTrayPlugin *plugin);
54
static void xfce_tray_plugin_construct (XfcePanelPlugin *panel_plugin);
58
/* register the plugin */
59
XFCE_PANEL_PLUGIN_REGISTER_INTERNAL_WITH_CHECK (xfce_tray_plugin_construct, xfce_tray_plugin_check);
64
xfce_tray_plugin_message (GtkMessageType type,
70
dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, type, GTK_BUTTONS_CLOSE, _("Notification Area"));
71
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s.", message);
72
gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
73
gtk_window_set_screen (GTK_WINDOW (dialog), screen);
76
gtk_dialog_run (GTK_DIALOG (dialog));
79
gtk_widget_destroy (dialog);
85
xfce_tray_plugin_check (GdkScreen *screen)
90
/* check if there is already a tray running */
91
running = xfce_tray_manager_check_running (screen);
96
/* TRANSLATORS: This message is shown in an info dialog when the users
97
add a notification area to a screen with a running systray manager. */
98
xfce_tray_plugin_message (GTK_MESSAGE_INFO, screen, _("There is already a notification area running on this screen"));
107
xfce_tray_plugin_update_position (XfceTrayPlugin *plugin)
109
XfceScreenPosition position;
113
GtkArrowType arrow_type;
115
_panel_return_if_fail (GTK_WIDGET_REALIZED (plugin->panel_plugin));
117
/* get the plugin position */
118
position = xfce_panel_plugin_get_screen_position (plugin->panel_plugin);
120
/* get the button position */
123
/* horizontal west */
124
case XFCE_SCREEN_POSITION_NW_H:
125
case XFCE_SCREEN_POSITION_SW_H:
126
arrow_type = GTK_ARROW_RIGHT;
129
/* horizontal east */
130
case XFCE_SCREEN_POSITION_N:
131
case XFCE_SCREEN_POSITION_NE_H:
132
case XFCE_SCREEN_POSITION_S:
133
case XFCE_SCREEN_POSITION_SE_H:
134
arrow_type = GTK_ARROW_LEFT;
138
case XFCE_SCREEN_POSITION_NW_V:
139
case XFCE_SCREEN_POSITION_NE_V:
140
arrow_type = GTK_ARROW_DOWN;
144
case XFCE_SCREEN_POSITION_W:
145
case XFCE_SCREEN_POSITION_SW_V:
146
case XFCE_SCREEN_POSITION_E:
147
case XFCE_SCREEN_POSITION_SE_V:
148
arrow_type = GTK_ARROW_UP;
153
/* get the screen information */
154
screen = gtk_widget_get_screen (GTK_WIDGET (plugin->panel_plugin));
155
mon = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (plugin->panel_plugin)->window);
156
gdk_screen_get_monitor_geometry (screen, mon, &geom);
157
gdk_window_get_root_origin (GTK_WIDGET (plugin->panel_plugin)->window, &x, &y);
159
/* get the position based on the screen position */
160
if (position == XFCE_SCREEN_POSITION_FLOATING_H)
161
arrow_type = ((x < (geom.x + geom.width / 2)) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
163
arrow_type = ((y < (geom.y + geom.height / 2)) ? GTK_ARROW_DOWN : GTK_ARROW_UP);
167
/* set the arrow type of the tray widget */
168
xfce_tray_widget_set_arrow_type (XFCE_TRAY_WIDGET (plugin->tray), arrow_type);
170
/* update the manager orientation */
171
xfce_tray_manager_set_orientation (plugin->manager, xfce_screen_position_get_orientation (position));
177
xfce_tray_plugin_icon_added (XfceTrayManager *manager,
179
XfceTrayPlugin *plugin)
183
/* get the application name */
184
name = xfce_tray_manager_get_application_name (icon);
186
/* add the icon to the widget */
187
xfce_tray_widget_add_with_name (XFCE_TRAY_WIDGET (plugin->tray), icon, name);
193
gtk_widget_show (icon);
199
xfce_tray_plugin_icon_removed (XfceTrayManager *manager,
201
XfceTrayPlugin *plugin)
203
/* remove from the tray */
204
gtk_container_remove (GTK_CONTAINER (plugin->tray), icon);
210
xfce_tray_plugin_lost_selection (XfceTrayManager *manager,
211
XfceTrayPlugin *plugin)
216
screen = gtk_widget_get_screen (GTK_WIDGET (plugin->panel_plugin));
218
/* TRANSLATORS: Bit of a weird text, but this is shown when for some
219
reason another tray takes the ownership of the tray icons and this
220
tray becomes unusable. */
221
xfce_tray_plugin_message (GTK_MESSAGE_WARNING, screen, _("The tray manager lost selection"));
226
static XfceTrayPlugin *
227
xfce_tray_plugin_new (XfcePanelPlugin *panel_plugin)
229
XfceTrayPlugin *plugin;
231
GError *error = NULL;
234
/* create structure */
235
plugin = panel_slice_new0 (XfceTrayPlugin);
238
plugin->panel_plugin = panel_plugin;
239
plugin->manager = NULL;
240
plugin->show_frame = TRUE;
242
/* create the frame */
243
plugin->frame = gtk_frame_new (NULL);
244
gtk_container_add (GTK_CONTAINER (panel_plugin), plugin->frame);
245
gtk_widget_show (plugin->frame);
247
/* create tray widget */
248
plugin->tray = xfce_tray_widget_new ();
249
gtk_container_add (GTK_CONTAINER (plugin->frame), plugin->tray);
250
gtk_widget_show (plugin->tray);
252
/* create a tray manager */
253
plugin->manager = xfce_tray_manager_new ();
255
/* read the plugin settings */
256
xfce_tray_plugin_read (plugin);
258
/* set frame shadow */
259
gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), plugin->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
262
screen = gtk_widget_get_screen (GTK_WIDGET (panel_plugin));
264
/* register the tray */
265
result = xfce_tray_manager_register (plugin->manager, screen, &error);
267
/* check for problems */
268
if (G_LIKELY (result == TRUE))
270
/* connect signals */
271
g_signal_connect (G_OBJECT (plugin->manager), "tray-icon-added", G_CALLBACK (xfce_tray_plugin_icon_added), plugin);
272
g_signal_connect (G_OBJECT (plugin->manager), "tray-icon-removed", G_CALLBACK (xfce_tray_plugin_icon_removed), plugin);
273
g_signal_connect (G_OBJECT (plugin->manager), "tray-lost-selection", G_CALLBACK (xfce_tray_plugin_lost_selection), plugin);
275
/* update the plugin position */
276
xfce_tray_plugin_update_position (plugin);
281
xfce_tray_plugin_message (GTK_MESSAGE_ERROR, screen, error->message);
284
g_error_free (error);
293
xfce_tray_plugin_screen_position_changed (XfceTrayPlugin *plugin,
294
XfceScreenPosition position)
296
/* update the plugin position */
297
xfce_tray_plugin_update_position (plugin);
303
xfce_tray_plugin_orientation_changed (XfceTrayPlugin *plugin,
304
GtkOrientation orientation)
306
/* update the plugin position */
307
xfce_tray_plugin_update_position (plugin);
313
xfce_tray_plugin_size_changed (XfceTrayPlugin *plugin,
316
/* set the border sizes */
317
gtk_container_set_border_width (GTK_CONTAINER (plugin->frame), (size > SMALL_PANEL_SIZE && plugin->show_frame) ? 1 : 0);
318
gtk_container_set_border_width (GTK_CONTAINER (plugin->tray), plugin->show_frame ? 1 : 0);
320
/* we handled the size of the plugin */
327
xfce_tray_plugin_read (XfceTrayPlugin *plugin)
335
/* get rc file name */
336
file = xfce_panel_plugin_lookup_rc_file (plugin->panel_plugin);
340
/* open the file, readonly */
341
rc = xfce_rc_simple_open (file, TRUE);
348
/* save global plugin settings */
349
xfce_rc_set_group (rc, "Global");
352
plugin->show_frame = xfce_rc_read_bool_entry (rc, "ShowFrame", TRUE);
354
xfce_tray_widget_set_rows (XFCE_TRAY_WIDGET (plugin->tray), xfce_rc_read_int_entry (rc, "Rows", 1));
356
if (G_LIKELY (plugin->manager))
358
/* list of known applications */
359
names = xfce_rc_get_entries (rc, "Applications");
361
if (G_LIKELY (names))
364
xfce_rc_set_group (rc, "Applications");
366
/* read their visibility */
367
for (i = 0; names[i] != NULL; i++)
369
/* whether the application is hidden */
370
hidden = xfce_rc_read_bool_entry (rc, names[i], FALSE);
372
/* add the application name */
373
xfce_tray_widget_name_add (XFCE_TRAY_WIDGET (plugin->tray), names[i], hidden);
381
/* close the rc file */
390
xfce_tray_plugin_write (XfceTrayPlugin *plugin)
398
/* get rc file name, create it if needed */
399
file = xfce_panel_plugin_save_location (plugin->panel_plugin, TRUE);
403
/* open the file, writable */
404
rc = xfce_rc_simple_open (file, FALSE);
411
/* save global plugin settings */
412
xfce_rc_set_group (rc, "Global");
415
xfce_rc_write_bool_entry (rc, "ShowFrame", plugin->show_frame);
416
xfce_rc_write_int_entry (rc, "Rows", xfce_tray_widget_get_rows (XFCE_TRAY_WIDGET (plugin->tray)));
418
if (G_LIKELY (plugin->manager))
420
/* get the list of known applications */
421
names = xfce_tray_widget_name_list (XFCE_TRAY_WIDGET (plugin->tray));
426
if (xfce_rc_has_group (rc, "Applications"))
427
xfce_rc_delete_group (rc, "Applications", FALSE);
431
/* save the list of known applications and their visibility */
432
xfce_rc_set_group (rc, "Applications");
434
/* save their state */
435
for (li = names; li != NULL; li = li->next)
437
/* get name and status */
439
hidden = xfce_tray_widget_name_hidden (XFCE_TRAY_WIDGET (plugin->tray), name);
442
xfce_rc_write_bool_entry (rc, name, hidden);
450
/* close the rc file */
459
xfce_tray_plugin_free (XfceTrayPlugin *plugin)
461
/* unregister manager */
462
xfce_tray_manager_unregister (plugin->manager);
465
g_object_unref (G_OBJECT (plugin->manager));
468
panel_slice_free (XfceTrayPlugin, plugin);
474
xfce_tray_plugin_construct (XfcePanelPlugin *panel_plugin)
476
XfceTrayPlugin *plugin;
478
/* create the tray panel plugin */
479
plugin = xfce_tray_plugin_new (panel_plugin);
481
/* set the action widgets and show configure */
482
xfce_panel_plugin_add_action_widget (panel_plugin, plugin->frame);
483
xfce_panel_plugin_add_action_widget (panel_plugin, plugin->tray);
484
xfce_panel_plugin_menu_show_configure (panel_plugin);
486
/* connect signals */
487
g_signal_connect_swapped (G_OBJECT (panel_plugin), "screen-position-changed",
488
G_CALLBACK (xfce_tray_plugin_screen_position_changed), plugin);
489
g_signal_connect_swapped (G_OBJECT (panel_plugin), "orientation-changed",
490
G_CALLBACK (xfce_tray_plugin_orientation_changed), plugin);
491
g_signal_connect_swapped (G_OBJECT (panel_plugin), "size-changed",
492
G_CALLBACK (xfce_tray_plugin_size_changed), plugin);
493
g_signal_connect_swapped (G_OBJECT (panel_plugin), "save",
494
G_CALLBACK (xfce_tray_plugin_write), plugin);
495
g_signal_connect_swapped (G_OBJECT (panel_plugin), "free-data",
496
G_CALLBACK (xfce_tray_plugin_free), plugin);
497
g_signal_connect_swapped (G_OBJECT (panel_plugin), "configure-plugin",
498
G_CALLBACK (xfce_tray_dialogs_configure), plugin);