From 88730a11adcbd075071dafa61e1633f2ad7a0926 Mon Sep 17 00:00:00 2001 From: Vincent Untz Date: Wed, 23 Feb 2011 00:34:17 +0100 Subject: na: Rewrite main.c to subclass PanelApplet as NaTrayApplet This is cleaner, and we'll be able to add style properties to this widget. Conflicts: applets/notification_area/main.c Conflicts: applets/notification_area/main.c --- applets/notification_area/Makefile.am | 2 +- applets/notification_area/main.c | 360 ++++++++++++++++------------------ applets/notification_area/main.h | 57 ++++++ 3 files changed, 230 insertions(+), 189 deletions(-) create mode 100644 applets/notification_area/main.h diff --git a/applets/notification_area/Makefile.am b/applets/notification_area/Makefile.am index 458e1875..cbd9d0b6 100644 --- a/applets/notification_area/Makefile.am +++ b/applets/notification_area/Makefile.am @@ -26,7 +26,7 @@ libtray_la_SOURCES = \ na-tray-manager.c \ na-tray-manager.h -NOTIFICATION_AREA_SOURCES = main.c +NOTIFICATION_AREA_SOURCES = main.c main.h NOTIFICATION_AREA_LDADD = \ ../../libmate-panel-applet/libmate-panel-applet-4.la \ diff --git a/applets/notification_area/main.c b/applets/notification_area/main.c index e5728174..853dad3f 100644 --- a/applets/notification_area/main.c +++ b/applets/notification_area/main.c @@ -37,252 +37,236 @@ #define NOTIFICATION_AREA_ICON "mate-panel-notification-area" -typedef struct { - MatePanelApplet* applet; - NaTray* tray; -} AppletData; +struct _NaTrayAppletPrivate +{ + NaTray *tray; +}; + +G_DEFINE_TYPE (NaTrayApplet, na_tray_applet, PANEL_TYPE_APPLET) -static GtkOrientation get_orientation_from_applet(MatePanelApplet* applet) +static GtkOrientation +get_gtk_orientation_from_applet_orient (PanelAppletOrient orient) { - GtkOrientation orientation; - - switch (mate_panel_applet_get_orient(applet)) - { - case MATE_PANEL_APPLET_ORIENT_LEFT: - case MATE_PANEL_APPLET_ORIENT_RIGHT: - orientation = GTK_ORIENTATION_VERTICAL; - break; - case MATE_PANEL_APPLET_ORIENT_UP: - case MATE_PANEL_APPLET_ORIENT_DOWN: - default: - orientation = GTK_ORIENTATION_HORIZONTAL; - break; - } - - return orientation; + switch (orient) + { + case MATE_PANEL_APPLET_ORIENT_LEFT: + case MATE_PANEL_APPLET_ORIENT_RIGHT: + return GTK_ORIENTATION_VERTICAL; + case MATE_PANEL_APPLET_ORIENT_UP: + case MATE_PANEL_APPLET_ORIENT_DOWN: + default: + return GTK_ORIENTATION_HORIZONTAL; + } + + g_assert_not_reached (); + + return GTK_ORIENTATION_HORIZONTAL; } -static void help_cb(GtkAction* action, AppletData* data) +static void +na_tray_applet_realize (GtkWidget *widget) { - GError* error = NULL; - char* uri; - #define NA_HELP_DOC "mate-user-guide" + NaTrayApplet *applet = NA_TRAY_APPLET (widget); + PanelAppletOrient orient; - uri = g_strdup_printf("help:%s/%s", NA_HELP_DOC, "panels-notification-area"); + GTK_WIDGET_CLASS (na_tray_applet_parent_class)->realize (widget); - gtk_show_uri(gtk_widget_get_screen(GTK_WIDGET(data->applet)), uri, gtk_get_current_event_time(), &error); + g_assert (applet->priv->tray == NULL); - g_free(uri); + orient = panel_applet_get_orient (PANEL_APPLET (widget)); - if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - { - g_error_free(error); - } - else if(error) - { - GtkWidget* dialog; - char* primary; + applet->priv->tray = na_tray_new_for_screen (gtk_widget_get_screen (widget), + get_gtk_orientation_from_applet_orient (orient)); - primary = g_markup_printf_escaped (_("Could not display help document '%s'"), NA_HELP_DOC); - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", primary); - - gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", error->message); + gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (applet->priv->tray)); + gtk_widget_show (GTK_WIDGET (applet->priv->tray)); +} - g_error_free(error); - g_free(primary); +static void +na_tray_applet_unrealize (GtkWidget *widget) +{ + NaTrayApplet *applet = NA_TRAY_APPLET (widget); - g_signal_connect(dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); + g_assert (applet->priv->tray != NULL); - gtk_window_set_icon_name (GTK_WINDOW (dialog), NOTIFICATION_AREA_ICON); - gtk_window_set_screen (GTK_WINDOW (dialog), gtk_widget_get_screen (GTK_WIDGET (data->applet))); - /* we have no parent window */ - gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE); - gtk_window_set_title (GTK_WINDOW (dialog), _("Error displaying help document")); + gtk_widget_destroy (GTK_WIDGET (applet->priv->tray)); + applet->priv->tray = NULL; - gtk_widget_show (dialog); - } + GTK_WIDGET_CLASS (na_tray_applet_parent_class)->unrealize (widget); } -static void about_cb(GtkAction* action, AppletData* data) +static inline gboolean +style_context_lookup_color (GtkStyleContext *context, + const gchar *color_name, + GdkColor *color) { - const gchar* authors[] = { - "Havoc Pennington ", - "Anders Carlsson ", - "Vincent Untz ", - NULL - }; - - const char* documenters[] = { - "Sun GNOME Documentation Team ", - NULL - }; - - const char copyright[] = \ - "Copyright \xc2\xa9 2002 Red Hat, Inc.\n" - "Copyright \xc2\xa9 2003-2006 Vincent Untz\n" - "Copyright \xc2\xa9 2011 Perberos"; - - mate_show_about_dialog(NULL, - "program-name", _("Notification Area"), - "authors", authors, - //"comments", _(comments), - "copyright", copyright, - "documenters", documenters, - "logo-icon-name", NOTIFICATION_AREA_ICON, - "translator-credits", _("translator-credits"), - "version", VERSION, - NULL); -} + GdkRGBA rgba; -static const GtkActionEntry menu_actions [] = { - { "SystemTrayHelp", GTK_STOCK_HELP, N_("_Help"), - NULL, NULL, - G_CALLBACK (help_cb) }, - { "SystemTrayAbout", GTK_STOCK_ABOUT, N_("_About"), - NULL, NULL, - G_CALLBACK (about_cb) } -}; - -#if GTK_CHECK_VERSION (3, 0, 0) -static void applet_change_background(MatePanelApplet* applet, MatePanelAppletBackgroundType type, GdkColor* color, cairo_pattern_t *pattern, AppletData* data) -#else -static void applet_change_background(MatePanelApplet* applet, MatePanelAppletBackgroundType type, GdkColor* color, GdkPixmap* pixmap, AppletData* data) -#endif -{ - na_tray_force_redraw(data->tray); -} + if (!gtk_style_context_lookup_color (context, color_name, &rgba)) + return FALSE; + color->red = rgba.red * 65535; + color->green = rgba.green * 65535; + color->blue = rgba.blue * 65535; -static void applet_change_orientation(MatePanelApplet* applet, MatePanelAppletOrient orient, AppletData* data) -{ - na_tray_set_orientation(data->tray, get_orientation_from_applet(applet)); -} - -static void applet_destroy(MatePanelApplet* applet, AppletData* data) -{ + return TRUE; } -static void free_applet_data(AppletData* data) +static void +na_tray_applet_style_updated (GtkWidget *widget) { - g_slice_free(AppletData, data); + NaTrayApplet *applet = NA_TRAY_APPLET (widget); + GtkStyleContext *context; + GdkRGBA rgba; + GdkColor fg; + GdkColor error; + GdkColor warning; + GdkColor success; + + GTK_WIDGET_CLASS (na_tray_applet_parent_class)->style_updated (widget); + + if (!applet->priv->tray) + return; + + context = gtk_widget_get_style_context (widget); + + gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &rgba); + fg.red = rgba.red * 65535; + fg.green = rgba.green * 65535; + fg.blue = rgba.blue * 65535; + + if (!style_context_lookup_color (context, "error_color", &error)) + error = fg; + if (!style_context_lookup_color (context, "warning_color", &warning)) + warning = fg; + if (!style_context_lookup_color (context, "success_color", &success)) + success = fg; + + na_tray_set_colors (applet->priv->tray, &fg, &error, &warning, &success); } -static void on_applet_realized(GtkWidget* widget, gpointer user_data) +static void +na_tray_applet_change_background (PanelApplet *panel_applet, + cairo_pattern_t *pattern) { - MatePanelApplet* applet; - AppletData* data; - NaTray* tray; - GtkActionGroup* action_group; - gchar* ui_path; + NaTrayApplet *applet = NA_TRAY_APPLET (panel_applet); - applet = MATE_PANEL_APPLET(widget); - data = g_object_get_data(G_OBJECT(widget), "system-tray-data"); + if (!applet->priv->tray) + return; - if (data != NULL) - { - return; - } - - tray = na_tray_new_for_screen(gtk_widget_get_screen(GTK_WIDGET(applet)), get_orientation_from_applet(applet)); - - data = g_slice_new(AppletData); - data->applet = applet; - data->tray = tray; - - g_object_set_data_full(G_OBJECT(applet), "system-tray-data", data, (GDestroyNotify) free_applet_data); - - g_signal_connect(applet, "change_orient", G_CALLBACK (applet_change_orientation), data); - g_signal_connect(applet, "change_background", G_CALLBACK (applet_change_background), data); - g_signal_connect(applet, "destroy", G_CALLBACK (applet_destroy), data); + na_tray_force_redraw (applet->priv->tray); +} - gtk_container_add(GTK_CONTAINER (applet), GTK_WIDGET (tray)); - gtk_widget_show(GTK_WIDGET(tray)); +static void +na_tray_applet_change_orient (PanelApplet *panel_applet, + PanelAppletOrient orient) +{ + NaTrayApplet *applet = NA_TRAY_APPLET (panel_applet); - action_group = gtk_action_group_new("ClockApplet Menu Actions"); - gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE); - gtk_action_group_add_actions(action_group, menu_actions, G_N_ELEMENTS(menu_actions), data); - ui_path = g_build_filename(NOTIFICATION_AREA_MENU_UI_DIR, "notification-area-menu.xml", NULL); - mate_panel_applet_setup_menu_from_file(applet, ui_path, action_group); - g_free(ui_path); - g_object_unref(action_group); + if (!applet->priv->tray) + return; + na_tray_set_orientation (applet->priv->tray, + get_gtk_orientation_from_applet_orient (orient)); } -static inline void force_no_focus_padding(GtkWidget* widget) +static inline void +force_no_focus_padding (GtkWidget *widget) { -#if GTK_CHECK_VERSION (3, 0, 0) - GtkCssProvider *provider; - - provider = gtk_css_provider_new (); - gtk_css_provider_load_from_data (provider, - "#na-tray {\n" - " -GtkWidget-focus-line-width: 0px;\n" - " -GtkWidget-focus-padding: 0px; }", - -1, NULL); - - gtk_style_context_add_provider (gtk_widget_get_style_context (widget), - GTK_STYLE_PROVIDER (provider), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - g_object_unref (provider); +##if GTK_CHECK_VERSION (3, 0, 0) + GtkCssProvider *provider; + + provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, + "NaTrayApplet {\n" + " -GtkWidget-focus-line-width: 0px;\n" + " -GtkWidget-focus-padding: 0px;\n" + "}", + -1, NULL); + gtk_style_context_add_provider (gtk_widget_get_style_context (widget), + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + g_object_unref (provider); #else - static gboolean first_time = TRUE; - - if (first_time) - { - gtk_rc_parse_string ("\n" + gtk_rc_parse_string ("\n" " style \"na-tray-style\"\n" " {\n" " GtkWidget::focus-line-width=0\n" " GtkWidget::focus-padding=0\n" " }\n" "\n" - " widget \"*.PanelAppletNaTray\" style \"na-tray-style\"\n" + " class \"NaTrayApplet\" style \"na-tray-style\"\n" "\n"); +#endif +} - first_time = FALSE; - } +static void +na_tray_applet_class_init (NaTrayAppletClass *class) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + PanelAppletClass *applet_class = PANEL_APPLET_CLASS (class); - /* El widget antes se llamaba na-tray - * - * Issue #27 - */ -#endif + widget_class->realize = na_tray_applet_realize; + widget_class->unrealize = na_tray_applet_unrealize; + widget_class->style_updated = na_tray_applet_style_updated; + applet_class->change_background = na_tray_applet_change_background; + applet_class->change_orient = na_tray_applet_change_orient; - gtk_widget_set_name(widget, "PanelAppletNaTray"); + g_type_class_add_private (class, sizeof (NaTrayAppletPrivate)); } -static gboolean applet_factory(MatePanelApplet* applet, const gchar* iid, gpointer user_data) +static void +na_tray_applet_init (NaTrayApplet *applet) { - AtkObject* atko; + AtkObject *atko; + + applet->priv = G_TYPE_INSTANCE_GET_PRIVATE (applet, NA_TYPE_TRAY_APPLET, + NaTrayAppletPrivate); - if (!(strcmp (iid, "NotificationArea") == 0 || strcmp (iid, "SystemTrayApplet") == 0)) - { - return FALSE; - } + /* Defer creating NaTray until applet is added to panel so + * gtk_widget_get_screen returns correct information */ + applet->priv->tray = NULL; - /* Defer loading until applet is added to panel so - * gtk_widget_get_screen returns correct information */ - g_signal_connect(GTK_WIDGET(applet), "realize", G_CALLBACK(on_applet_realized), NULL); + atko = gtk_widget_get_accessible (GTK_WIDGET (applet)); + atk_object_set_name (atko, _("Panel Notification Area")); - atko = gtk_widget_get_accessible (GTK_WIDGET (applet)); - atk_object_set_name (atko, _("Panel Notification Area")); + panel_applet_set_flags (PANEL_APPLET (applet), + PANEL_APPLET_HAS_HANDLE|PANEL_APPLET_EXPAND_MINOR); - mate_panel_applet_set_flags(applet, MATE_PANEL_APPLET_HAS_HANDLE | MATE_PANEL_APPLET_EXPAND_MINOR); + panel_applet_set_background_widget (PANEL_APPLET (applet), + GTK_WIDGET (applet)); - mate_panel_applet_set_background_widget(applet, GTK_WIDGET(applet)); + force_no_focus_padding (GTK_WIDGET (applet)); +} + +static gboolean +applet_factory (PanelApplet *applet, + const gchar *iid, + gpointer user_data) +{ + if (!(strcmp (iid, "NotificationArea") == 0 || + strcmp (iid, "SystemTrayApplet") == 0)) + return FALSE; - force_no_focus_padding(GTK_WIDGET(applet)); +#ifndef NOTIFICATION_AREA_INPROCESS + gtk_window_set_default_icon_name (NOTIFICATION_AREA_ICON); +#endif - #ifndef NOTIFICATION_AREA_INPROCESS - gtk_window_set_default_icon_name(NOTIFICATION_AREA_ICON); - #endif + gtk_widget_show_all (GTK_WIDGET (applet)); - gtk_widget_show_all(GTK_WIDGET(applet)); - return TRUE; + return TRUE; } #ifdef NOTIFICATION_AREA_INPROCESS - MATE_PANEL_APPLET_IN_PROCESS_FACTORY("NotificationAreaAppletFactory", PANEL_TYPE_APPLET, "NotificationArea", applet_factory, NULL) + MATE_PANEL_APPLET_IN_PROCESS_FACTORY ("NotificationAreaAppletFactory", + NA_TYPE_TRAY_APPLET, + "NotificationArea", + applet_factory, + NULL) #else - MATE_PANEL_APPLET_OUT_PROCESS_FACTORY("NotificationAreaAppletFactory", PANEL_TYPE_APPLET, "NotificationArea", applet_factory, NULL) + MATE_PANEL_APPLET_OUT_PROCESS_FACTORY ("NotificationAreaAppletFactory", + NA_TYPE_TRAY_APPLET, + "NotificationArea", + applet_factory, + NULL) #endif diff --git a/applets/notification_area/main.h b/applets/notification_area/main.h new file mode 100644 index 00000000..1038c6f2 --- /dev/null +++ b/applets/notification_area/main.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2002 Red Hat, Inc. + * Copyright (C) 2003-2006 Vincent Untz + * + * 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. + */ + + +#ifndef __NA_TRAY_APPLET_H__ +#define __NA_TRAY_APPLET_H__ + +#include + +G_BEGIN_DECLS + +#define NA_TYPE_TRAY_APPLET (na_tray_applet_get_type ()) +#define NA_TRAY_APPLET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NA_TYPE_TRAY_APPLET, NaTrayApplet)) +#define NA_TRAY_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NA_TYPE_TRAY_APPLET, NaTrayAppletClass)) +#define NA_IS_TRAY_APPLET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NA_TYPE_TRAY_APPLET)) +#define NA_IS_TRAY_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NA_TYPE_TRAY_APPLET)) +#define NA_TRAY_APPLET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NA_TYPE_TRAY_APPLET, NaTrayAppletClass)) + +typedef struct _NaTrayApplet NaTrayApplet; +typedef struct _NaTrayAppletClass NaTrayAppletClass; +typedef struct _NaTrayAppletPrivate NaTrayAppletPrivate; + +struct _NaTrayApplet +{ + PanelApplet parent_object; + + /*< private >*/ + NaTrayAppletPrivate *priv; +}; + +struct _NaTrayAppletClass +{ + PanelAppletClass parent_class; +}; + +GType na_tray_applet_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __NA_TRAY_APPLET_H__ */ -- cgit v1.2.1