Commit a1b7be31 authored by Nick Schermer's avatar Nick Schermer
Browse files

* plugins/systray: Rewrite of the system tray plugin. This should

  fix the icon size problems (Bugs 3213, 3176, 962, 3478 and 3417), 
  add option to hide icons in the   tray, sort icons by application 
  name and support multiple lines based on the   panel size. The 
  tray manager code is now integrated in the plugin, so it can be
  removed from libxfcegui4.
* NEWS: update
* po/: merge strings


(Old svn revision: 26037)
parent c52b19f1
......@@ -7,6 +7,11 @@
- Separator can have different styles: space, expanded space, line (default),
handle and old-style dotted handle. Initial patch by Landry Breuil. (Jasper)
- Complete rewrite of the clock plugin. (Nick)
- Rewrite of the system tray plugin. This should fix the icon size problems
(Bugs 3213, 3176, 962, 3478 and 3417), add option to hide icons in the
tray, sort icons by application name and support multiple lines based on the
panel size. The tray manager code is now integrated in the plugin, so it
can be removed from libxfcegui4. (Nick)
- Fix area that is off-limits to other windows (_NET_WM_STRUT hints) for a
Xinerama setup with differently sized monitors (Bug #3097). (Jasper)
- Completely rewritten launcher (Bugs 2336, 2365, 1323, 2262 and 1225)
......
......@@ -11,11 +11,24 @@ plugindir = \
plugin_LTLIBRARIES = \
libsystray.la
libsystray_built_sources = \
xfce-tray-marshal.c \
xfce-tray-marshal.h
libsystray_la_SOURCES = \
systray.c
$(libsystray_built_sources) \
xfce-tray-dialogs.c \
xfce-tray-dialogs.h \
xfce-tray-manager.c \
xfce-tray-manager.h \
xfce-tray-plugin.c \
xfce-tray-plugin.h \
xfce-tray-widget.c \
xfce-tray-widget.h
libsystray_la_CFLAGS = \
$(LIBX11_CFLAGS) \
$(GTK_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
$(LIBXFCEGUI4_CFLAGS) \
......@@ -33,6 +46,7 @@ endif
libsystray_la_LIBADD = \
$(top_builddir)/libxfce4panel/libxfce4panel.la \
$(LIBX11_LIBS) \
$(GTK_LIBS) \
$(LIBXFCE4UTIL_LIBS) \
$(LIBXFCEGUI4_LIBS)
......@@ -59,10 +73,44 @@ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
@INTLTOOL_DESKTOP_RULE@
EXTRA_DIST = \
$(desktop_in_in_files)
$(desktop_in_in_files) \
xfce-tray-marshal.list
CLEANFILES = \
xgen-xtmc \
xgen-xtmh
#
# Rules to auto-generate built sources
#
if MAINTAINER_MODE
DISTCLEANFILES = \
$(desktop_DATA) \
$(desktop_in_files)
$(desktop_in_files) \
$(libsystray_built_sources) \
stamp-xfce-tray-marshal.h
BUILT_SOURCES = \
$(libsystray_built_sources)
xfce-tray-marshal.h: stamp-xfce-tray-marshal.h
@true
stamp-xfce-tray-marshal.h: $(srcdir)/xfce-tray-marshal.list Makefile
( cd $(srcdir) && glib-genmarshal \
--prefix="_xfce_tray_marshal" \
--header xfce-tray-marshal.list \
| sed -e 's/marshal_data);$$/marshal_data) G_GNUC_INTERNAL;/' ) >> xgen-xtmh \
&& ( cmp -s xgen-xtmh xfce-tray-marshal.h || cp xgen-xtmh xfce-tray-marshal.h ) \
&& rm -f xgen-xtmh \
&& echo timestamp > $(@F)
xfce-tray-marshal.c: xfce-tray-marshal.h Makefile
( cd $(srcdir) && glib-genmarshal \
--prefix="_xfce_tray_marshal" \
--body xfce-tray-marshal.list ) >> xgen-xtmc \
&& cp xgen-xtmc xfce-tray-marshal.c \
&& rm -f xgen-xtmc
endif
# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
/* vim: set expandtab ts=8 sw=4: */
/* $Id$
*
* Copyright © 2005 Jasper Huijsmans <jasper@xfce.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gtk/gtk.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfcegui4/libxfcegui4.h>
#include <libxfce4panel/xfce-panel-plugin.h>
#include <libxfce4panel/xfce-hvbox.h>
typedef struct
{
XfcePanelPlugin *plugin;
XfceSystemTray *tray;
guint tray_registered : 1;
GtkWidget *frame;
GtkWidget *align;
GtkWidget *iconbox;
guint show_frame : 1;
}
Systray;
static void systray_properties_dialog (XfcePanelPlugin *plugin,
Systray *systray);
static void systray_free_data (XfcePanelPlugin *plugin, Systray *systray);
static void systray_construct (XfcePanelPlugin *plugin);
static gboolean systray_check (GdkScreen *screen);
/* -------------------------------------------------------------------- *
* Systray *
* -------------------------------------------------------------------- */
static gboolean
systray_check (GdkScreen *screen)
{
Screen *scr = GDK_SCREEN_XSCREEN (screen);
if (xfce_system_tray_check_running (scr))
{
xfce_info (_("There is already a system tray running on this "
"screen"));
return FALSE;
}
return TRUE;
}
static gboolean
register_tray (Systray * systray)
{
GError *error = NULL;
Screen *scr = GDK_SCREEN_XSCREEN (gtk_widget_get_screen (systray->frame));
if (!systray_check (gtk_widget_get_screen (systray->frame)))
{
xfce_info (_("There is already a system tray running on this "
"screen"));
return FALSE;
}
else if (!xfce_system_tray_register (systray->tray, scr, &error))
{
xfce_err (_("Unable to register system tray: %s"), error->message);
g_error_free (error);
return FALSE;
}
return TRUE;
}
static void
icon_docked (XfceSystemTray * tray, GtkWidget * icon, Systray * systray)
{
if (systray->tray_registered)
{
gtk_widget_show (icon);
gtk_box_pack_start (GTK_BOX (systray->iconbox), icon,
FALSE, FALSE, 0);
}
}
static void
icon_undocked (XfceSystemTray * tray, GtkWidget * icon, Systray *systray)
{
if (systray->tray_registered)
{
gtk_widget_hide (systray->iconbox);
gtk_container_remove (GTK_CONTAINER (systray->iconbox), icon);
gtk_widget_show (systray->iconbox);
gtk_widget_queue_draw (systray->iconbox);
}
}
static void
message_new (XfceSystemTray * tray, GtkWidget * icon, glong id,
glong timeout, const gchar * text)
{
g_print ("++ notification: %s\n", text);
}
static gboolean
systray_remove (Systray *systray)
{
GtkWidget *widget = GTK_WIDGET (systray->plugin);
systray_free_data (systray->plugin, systray);
gtk_widget_destroy (widget);
return FALSE;
}
static void
systray_start (Systray *systray)
{
if (!systray->tray_registered)
{
systray->tray_registered = register_tray (systray);
if (!systray->tray_registered)
{
g_idle_add ((GSourceFunc)systray_remove, systray);
}
}
}
static void
systray_stop (Systray *systray)
{
if (systray->tray_registered)
{
xfce_system_tray_unregister (systray->tray);
systray->tray_registered = FALSE;
}
}
/* -------------------------------------------------------------------- *
* Panel Plugin Interface *
* -------------------------------------------------------------------- */
/* Register with the panel */
XFCE_PANEL_PLUGIN_REGISTER_INTERNAL_WITH_CHECK (systray_construct,
systray_check);
/* Interface Implementation */
static void
systray_orientation_changed (XfcePanelPlugin *plugin,
GtkOrientation orientation,
Systray *systray)
{
xfce_hvbox_set_orientation (XFCE_HVBOX (systray->iconbox), orientation);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_alignment_set_padding (GTK_ALIGNMENT (systray->align),
0, 0, 3, 3);
}
else
{
gtk_alignment_set_padding (GTK_ALIGNMENT (systray->align),
3, 3, 0, 0);
}
}
static gboolean
systray_set_size (XfcePanelPlugin *plugin, int size, Systray *systray)
{
int border = size > 26 ? 1 : 0;
gtk_container_set_border_width (GTK_CONTAINER (systray->frame), border);
size = size - (2*border) - 2 - MAX (systray->frame->style->xthickness,
systray->frame->style->ythickness);
if (xfce_panel_plugin_get_orientation (plugin)
== GTK_ORIENTATION_HORIZONTAL)
{
gtk_widget_set_size_request (systray->iconbox, -1, size);
}
else
{
gtk_widget_set_size_request (systray->iconbox, size, -1);
}
return TRUE;
}
static void
systray_free_data (XfcePanelPlugin *plugin, Systray *systray)
{
GtkWidget *dlg = g_object_get_data (G_OBJECT (plugin), "dialog");
if (dlg)
gtk_widget_destroy (dlg);
systray_stop (systray);
panel_slice_free (Systray, systray);
}
static void
systray_read_rc_file (XfcePanelPlugin *plugin, Systray *systray)
{
char *file;
XfceRc *rc;
int show_frame = 1;
if ((file = xfce_panel_plugin_lookup_rc_file (plugin)) != NULL)
{
rc = xfce_rc_simple_open (file, TRUE);
g_free (file);
if (rc != NULL)
{
show_frame = xfce_rc_read_int_entry (rc, "show_frame", 1);
xfce_rc_close (rc);
}
}
systray->show_frame = (show_frame != 0);
}
static void
systray_write_rc_file (XfcePanelPlugin *plugin, Systray *systray)
{
char *file;
XfceRc *rc;
if (!(file = xfce_panel_plugin_save_location (plugin, TRUE)))
return;
rc = xfce_rc_simple_open (file, FALSE);
g_free (file);
if (!rc)
return;
xfce_rc_write_int_entry (rc, "show_frame", systray->show_frame);
xfce_rc_close (rc);
}
/* create widgets and connect to signals */
static void
systray_construct (XfcePanelPlugin *plugin)
{
Systray *systray = panel_slice_new0 (Systray);
g_signal_connect (plugin, "orientation-changed",
G_CALLBACK (systray_orientation_changed), systray);
g_signal_connect (plugin, "size-changed",
G_CALLBACK (systray_set_size), systray);
g_signal_connect (plugin, "free-data",
G_CALLBACK (systray_free_data), systray);
g_signal_connect (plugin, "save",
G_CALLBACK (systray_write_rc_file), systray);
xfce_panel_plugin_menu_show_configure (plugin);
g_signal_connect (plugin, "configure-plugin",
G_CALLBACK (systray_properties_dialog), systray);
systray->plugin = plugin;
systray_read_rc_file (plugin, systray);
systray->frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (systray->frame),
systray->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
gtk_widget_show (systray->frame);
gtk_container_add (GTK_CONTAINER (plugin), systray->frame);
systray->align = gtk_alignment_new (0, 0, 1, 1);
gtk_widget_show (systray->align);
gtk_container_add (GTK_CONTAINER (systray->frame), systray->align);
if (xfce_panel_plugin_get_orientation (plugin) ==
GTK_ORIENTATION_HORIZONTAL)
{
systray->iconbox =
xfce_hvbox_new (GTK_ORIENTATION_HORIZONTAL, FALSE, 3);
gtk_alignment_set_padding (GTK_ALIGNMENT (systray->align),
0, 0, 3, 3);
}
else
{
systray->iconbox =
xfce_hvbox_new (GTK_ORIENTATION_VERTICAL, FALSE, 3);
gtk_alignment_set_padding (GTK_ALIGNMENT (systray->align),
3, 3, 0, 0);
}
gtk_widget_show (systray->iconbox);
gtk_container_add (GTK_CONTAINER (systray->align), systray->iconbox);
systray_set_size (plugin, xfce_panel_plugin_get_size (plugin), systray);
systray->tray = xfce_system_tray_new ();
g_signal_connect (systray->tray, "icon_docked", G_CALLBACK (icon_docked),
systray);
g_signal_connect (systray->tray, "icon_undocked",
G_CALLBACK (icon_undocked), systray);
g_signal_connect (systray->tray, "message_new", G_CALLBACK (message_new),
systray);
systray_start (systray);
}
/* -------------------------------------------------------------------- *
* Configuration Dialog *
* -------------------------------------------------------------------- */
static void
show_frame_toggled (GtkToggleButton *tb, Systray *systray)
{
systray->show_frame = gtk_toggle_button_get_active (tb);
gtk_frame_set_shadow_type (GTK_FRAME (systray->frame),
systray->show_frame ? GTK_SHADOW_IN : GTK_SHADOW_NONE);
}
static void
systray_dialog_response (GtkWidget *dlg, int reponse,
Systray *systray)
{
g_object_set_data (G_OBJECT (systray->plugin), "dialog", NULL);
gtk_widget_destroy (dlg);
xfce_panel_plugin_unblock_menu (systray->plugin);
systray_write_rc_file (systray->plugin, systray);
}
static void
systray_properties_dialog (XfcePanelPlugin *plugin, Systray *systray)
{
GtkWidget *dlg, *vbox, *cb;
xfce_panel_plugin_block_menu (plugin);
dlg = xfce_titled_dialog_new_with_buttons (_("System Tray"), NULL,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
NULL);
gtk_window_set_screen (GTK_WINDOW (dlg),
gtk_widget_get_screen (GTK_WIDGET (plugin)));
g_object_set_data (G_OBJECT (plugin), "dialog", dlg);
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
gtk_window_set_icon_name (GTK_WINDOW (dlg), "xfce4-settings");
g_signal_connect (dlg, "response", G_CALLBACK (systray_dialog_response),
systray);
gtk_container_set_border_width (GTK_CONTAINER (dlg), 2);
vbox = gtk_vbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_widget_show (vbox);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), vbox,
TRUE, TRUE, 0);
cb = gtk_check_button_new_with_mnemonic (_("Show _frame"));
gtk_widget_show (cb);
gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb),
systray->show_frame);
g_signal_connect (cb, "toggled", G_CALLBACK (show_frame_toggled),
systray);
gtk_widget_show (dlg);
}
/* $Id$ */
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define XFCE_TRAY_DIALOG_ICON_SIZE 16
#include <gtk/gtk.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfcegui4/xfce-titled-dialog.h>
#include <libxfcegui4/xfce-widget-helpers.h>
#include <libxfce4panel/xfce-panel-plugin.h>
#include <libxfce4panel/xfce-panel-macros.h>
#include "xfce-tray-manager.h"
#include "xfce-tray-widget.h"
#include "xfce-tray-plugin.h"
#include "xfce-tray-dialogs.h"
enum
{
APPLICATION_ICON,
APPLICATION_NAME,
APPLICATION_HIDDEN,
APPLICATION_DATA,
N_COLUMNS
};
/* prototypes */
static gchar *xfce_tray_dialogs_camel_case (const gchar *text);
static GdkPixbuf *xfce_tray_dialogs_icon (GtkIconTheme *icon_theme,
const gchar *name);
static void xfce_tray_dialogs_show_frame_toggled (GtkToggleButton *button,
XfceTrayPlugin *plugin);
static void xfce_tray_dialogs_treeview_toggled (GtkCellRendererToggle *widget,
gchar *path,
GtkWidget *treeview);
static void xfce_tray_dialogs_free_store (GtkListStore *store);
static void xfce_tray_dialogs_configure_response (GtkWidget *dialog,
gint response,
XfceTrayPlugin *plugin);
static gchar *
xfce_tray_dialogs_camel_case (const gchar *text)
{
const gchar *t;
gboolean upper = TRUE;
gunichar c;
GString *result;
/* allocate a new string for the result */
result = g_string_sized_new (32);
/* convert the input text */
for (t = text; *t != '\0'; t = g_utf8_next_char (t))
{
/* check the next char */
c = g_utf8_get_char (t);
if (g_unichar_isspace (c))
{
upper = TRUE;
}
else if (upper)
{
c = g_unichar_toupper (c);
upper = FALSE;
}
else
{
c = g_unichar_tolower (c);
}
/* append the char to the result */
g_string_append_unichar (result, c);
}
return g_string_free (result, FALSE);
}