diff --git a/plugins/clock/clock.c b/plugins/clock/clock.c --- a/plugins/clock/clock.c +++ b/plugins/clock/clock.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2007-2010 Nick Schermer + * Copyright (C) 2012 Guido Berhoerster * * This library 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 @@ -68,8 +69,15 @@ static gboolean clock_plugin_size_change static void clock_plugin_size_ratio_changed (XfcePanelPlugin *panel_plugin); static void clock_plugin_mode_changed (XfcePanelPlugin *panel_plugin, XfcePanelPluginMode mode); +static void clock_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin, + XfceScreenPosition position); static void clock_plugin_configure_plugin (XfcePanelPlugin *panel_plugin); static void clock_plugin_set_mode (ClockPlugin *plugin); +static void clock_plugin_reposition_calendar (ClockPlugin *plugin); +static void clock_plugin_calendar_show_event (GtkWidget *calendar_window, + gpointer user_data); +static void clock_plugin_popup_calendar (ClockPlugin *plugin); +static void clock_plugin_hide_calendar (ClockPlugin *plugin); static gboolean clock_plugin_tooltip (gpointer user_data); static gboolean clock_plugin_timeout_running (gpointer user_data); static void clock_plugin_timeout_destroyed (gpointer user_data); @@ -113,6 +121,8 @@ struct _ClockPlugin GtkWidget *clock; GtkWidget *frame; + GtkWidget *calendar_window; + GtkWidget *calendar; guint show_frame : 1; gchar *command; @@ -197,6 +207,7 @@ clock_plugin_class_init (ClockPluginClas plugin_class->free_data = clock_plugin_free_data; plugin_class->size_changed = clock_plugin_size_changed; plugin_class->mode_changed = clock_plugin_mode_changed; + plugin_class->screen_position_changed = clock_plugin_screen_position_changed; plugin_class->configure_plugin = clock_plugin_configure_plugin; g_object_class_install_property (gobject_class, @@ -241,6 +252,8 @@ clock_plugin_class_init (ClockPluginClas static void clock_plugin_init (ClockPlugin *plugin) { + GtkWidget *calendar_frame; + plugin->mode = CLOCK_PLUGIN_MODE_DEFAULT; plugin->clock = NULL; plugin->show_frame = TRUE; @@ -253,6 +266,28 @@ clock_plugin_init (ClockPlugin *plugin) gtk_container_add (GTK_CONTAINER (plugin), plugin->frame); gtk_frame_set_shadow_type (GTK_FRAME (plugin->frame), GTK_SHADOW_ETCHED_IN); gtk_widget_show (plugin->frame); + + plugin->calendar_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_type_hint (GTK_WINDOW (plugin->calendar_window), + GDK_WINDOW_TYPE_HINT_UTILITY); + gtk_window_set_decorated (GTK_WINDOW (plugin->calendar_window), FALSE); + gtk_window_set_resizable (GTK_WINDOW (plugin->calendar_window), FALSE); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW (plugin->calendar_window), TRUE); + gtk_window_set_skip_pager_hint(GTK_WINDOW (plugin->calendar_window), TRUE); + gtk_window_set_keep_above (GTK_WINDOW (plugin->calendar_window), TRUE); + gtk_window_stick (GTK_WINDOW (plugin->calendar_window)); + + calendar_frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (calendar_frame), GTK_SHADOW_OUT); + gtk_container_add (GTK_CONTAINER (plugin->calendar_window), calendar_frame); + + plugin->calendar = gtk_calendar_new (); + gtk_calendar_set_display_options (GTK_CALENDAR (plugin->calendar), + GTK_CALENDAR_SHOW_HEADING + | GTK_CALENDAR_SHOW_DAY_NAMES); + g_signal_connect (G_OBJECT (plugin->calendar_window), "show", + G_CALLBACK (clock_plugin_calendar_show_event), plugin); + gtk_container_add (GTK_CONTAINER (calendar_frame), plugin->calendar); } @@ -333,6 +368,11 @@ clock_plugin_set_property (GObject case PROP_COMMAND: g_free (plugin->command); plugin->command = g_value_dup_string (value); + /* + * ensure the calendar window is hidden since a non-empty command disables + * toggling + */ + clock_plugin_hide_calendar (plugin); break; case PROP_ROTATE_VERTICALLY: @@ -396,19 +436,36 @@ clock_plugin_button_press_event (GtkWidg ClockPlugin *plugin = XFCE_CLOCK_PLUGIN (widget); GError *error = NULL; - if (event->button == 1 - && event->type == GDK_2BUTTON_PRESS - && !exo_str_is_empty (plugin->command)) + if (event->button == 1) { - /* launch command */ - if (!xfce_spawn_command_line_on_screen (gtk_widget_get_screen (widget), - plugin->command, FALSE, FALSE, &error)) + if (event->type == GDK_BUTTON_PRESS && + exo_str_is_empty (plugin->command)) { - xfce_dialog_show_error (NULL, error, _("Failed to execute clock command")); - g_error_free (error); + /* toggle calendar window visibility */ + if (gtk_widget_get_visible (GTK_WIDGET (plugin->calendar_window))) + { + clock_plugin_hide_calendar (plugin); + } + else + { + clock_plugin_popup_calendar (plugin); + } } + else if (event->type == GDK_2BUTTON_PRESS + && !exo_str_is_empty (plugin->command)) + { + /* launch command */ + if (!xfce_spawn_command_line_on_screen (gtk_widget_get_screen (widget), + plugin->command, FALSE, + FALSE, &error)) + { + xfce_dialog_show_error (NULL, error, + _("Failed to execute clock command")); + g_error_free (error); + } - return TRUE; + return TRUE; + } } return (*GTK_WIDGET_CLASS (clock_plugin_parent_class)->button_press_event) (widget, event); @@ -453,6 +510,12 @@ clock_plugin_free_data (XfcePanelPlugin if (plugin->tooltip_timeout != NULL) clock_plugin_timeout_free (plugin->tooltip_timeout); + if (plugin->calendar_window != NULL) + { + gtk_widget_destroy (plugin->calendar_window); + plugin->calendar_window = NULL; + plugin->calendar = NULL; + } g_free (plugin->tooltip_format); g_free (plugin->command); } @@ -513,6 +576,11 @@ clock_plugin_size_changed (XfcePanelPlug gtk_widget_set_size_request (GTK_WIDGET (panel_plugin), size, ratio_size); } + if (gtk_widget_get_visible (GTK_WIDGET (plugin->calendar_window))) + { + clock_plugin_reposition_calendar (XFCE_CLOCK_PLUGIN (panel_plugin)); + } + return TRUE; } @@ -547,6 +615,19 @@ clock_plugin_mode_changed (XfcePanelPlug static void +clock_plugin_screen_position_changed (XfcePanelPlugin *panel_plugin, + XfceScreenPosition position) +{ + ClockPlugin *plugin = XFCE_CLOCK_PLUGIN (panel_plugin); + if (gtk_widget_get_visible (GTK_WIDGET (plugin->calendar_window))) + { + clock_plugin_reposition_calendar (plugin); + } +} + + + +static void clock_plugin_configure_plugin_mode_changed (GtkComboBox *combo, ClockPluginDialog *dialog) { @@ -880,6 +961,55 @@ clock_plugin_set_mode (ClockPlugin *plug +static void +clock_plugin_reposition_calendar (ClockPlugin *plugin) +{ + gint x; + gint y; + + xfce_panel_plugin_position_widget (XFCE_PANEL_PLUGIN (plugin), + GTK_WIDGET (plugin->calendar_window), + NULL, &x, &y); + gtk_window_move (GTK_WINDOW (plugin->calendar_window), x, y); +} + + + +static void +clock_plugin_calendar_show_event (GtkWidget *calendar_window, + gpointer user_data) +{ + ClockPlugin *plugin = XFCE_CLOCK_PLUGIN (user_data); + struct tm tm; + + clock_plugin_reposition_calendar (plugin); + + clock_plugin_get_localtime (&tm); + gtk_calendar_select_month (GTK_CALENDAR (plugin->calendar), tm.tm_mon, + 1900 + tm.tm_year); + gtk_calendar_select_day (GTK_CALENDAR (plugin->calendar), tm.tm_mday); +} + + + +static void +clock_plugin_popup_calendar (ClockPlugin *plugin) +{ + gtk_widget_show_all (GTK_WIDGET (plugin->calendar_window)); + xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), TRUE); +} + + + +static void +clock_plugin_hide_calendar (ClockPlugin *plugin) +{ + gtk_widget_hide (GTK_WIDGET (plugin->calendar_window)); + xfce_panel_plugin_block_autohide (XFCE_PANEL_PLUGIN (plugin), FALSE); +} + + + static gboolean clock_plugin_tooltip (gpointer user_data) {