From b08bc130853b2f737eb47113357513f5e937eb47 Mon Sep 17 00:00:00 2001 From: info-cppsp Date: Tue, 6 Feb 2018 16:24:14 +0100 Subject: Drawer cleanup and fix arrow behavior *Drawer coding style cleanup *Drawer code organized *Rearranged and labeled code *Drawer fix arrows *Fixed hide code for drawer in toplevel. *fix #528 *fix #704 --- mate-panel/drawer-private.h | 146 ++++++ mate-panel/drawer.c | 1067 ++++++++++++++++++++++--------------------- mate-panel/drawer.h | 51 ++- mate-panel/panel-toplevel.c | 18 +- 4 files changed, 722 insertions(+), 560 deletions(-) create mode 100644 mate-panel/drawer-private.h diff --git a/mate-panel/drawer-private.h b/mate-panel/drawer-private.h new file mode 100644 index 00000000..b71ef818 --- /dev/null +++ b/mate-panel/drawer-private.h @@ -0,0 +1,146 @@ +/* + * MATE panel drawer module. + * + * List static function prototypes separate + * to prevent errors when compiling panel.c + * + * Authors: info@cppsp.de + */ + + +#ifndef DRAWER_PRIVATE_H +#define DRAWER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Internal functions */ +/* event handlers */ + +static void drawer_click (GtkWidget *widget, + Drawer *drawer); + +static void drawer_focus_panel_widget (Drawer *drawer, + GtkDirectionType direction); + +static gboolean key_press_drawer (GtkWidget *widget, + GdkEventKey *event, + Drawer *drawer); + +static gboolean key_press_drawer_widget (GtkWidget *widget, + GdkEventKey *event, + Drawer *drawer); + + /* drag and drop handlers */ + +static void drag_data_get_cb (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time, + Drawer *drawer); + +static gboolean drag_motion_cb (GtkWidget *widget, + GdkDragContext *context, + int x, + int y, + guint time_, + Drawer *drawer); + +static gboolean drag_drop_cb (GtkWidget *widget, + GdkDragContext *context, + int x, + int y, + guint time_, + Drawer *drawer); + +static void drag_data_received_cb (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time_, + Drawer *drawer); + +static gboolean close_drawer_in_idle (gpointer data); + +static void queue_drawer_close_for_drag (Drawer *drawer); + +static void drag_leave_cb (GtkWidget *widget, + GdkDragContext *context, + guint time_, + Drawer *drawer); + + /* load_drawer_applet handlers */ + +static void drawer_button_size_allocated (GtkWidget *widget, + GtkAllocation *alloc, + Drawer *drawer); + +static gboolean drawer_changes_enabled (void); + + /* gsettings handlers */ + +static void panel_drawer_custom_icon_changed (GSettings *settings, + gchar *key, + Drawer *drawer); + +static void panel_drawer_tooltip_changed (GSettings *settings, + gchar *key, + Drawer *drawer); + + /* destroy handlers */ + +static void toplevel_destroyed (GtkWidget *widget, + Drawer *drawer); + +static void destroy_drawer (GtkWidget *widget, + Drawer *drawer); + +static void drawer_deletion_response (GtkWidget *dialog, + int response, + Drawer *drawer); + +/* end event handlers */ + +static PanelToplevel *create_drawer_toplevel (const char *drawer_id, + GSettings *settings); + +static void set_tooltip_and_name (Drawer *drawer, + const char *tooltip); + +static Drawer *create_drawer_applet (PanelToplevel *toplevel, + PanelToplevel *parent_toplevel, + const char *tooltip, + const char *custom_icon, + gboolean use_custom_icon, + PanelOrientation orientation); + +static void panel_drawer_connect_to_gsettings (Drawer *drawer); + +static void load_drawer_applet (char *toplevel_id, + GSettings *settings, + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip, + PanelToplevel *parent_toplevel, + gboolean locked, + int pos, + gboolean exactpos, + const char *id); + +static void panel_drawer_prepare (const char *drawer_id, + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip, + char **attached_toplevel_id); + + +#ifdef __cplusplus +} +#endif + +#endif /* DRAWER_PRIVATE_H */ diff --git a/mate-panel/drawer.c b/mate-panel/drawer.c index 917e4836..5875ef65 100644 --- a/mate-panel/drawer.c +++ b/mate-panel/drawer.c @@ -7,6 +7,7 @@ * George Lebl */ + #include #include #include @@ -21,6 +22,7 @@ #include #include "drawer.h" +#include "drawer-private.h" #include "applet.h" #include "button-widget.h" @@ -33,118 +35,97 @@ #include "panel-icon-names.h" #include "panel-schemas.h" -static void -drawer_click (GtkWidget *w, Drawer *drawer) -{ - if (!panel_toplevel_get_is_hidden (drawer->toplevel)) - panel_toplevel_hide (drawer->toplevel, FALSE, -1); - else - panel_toplevel_unhide (drawer->toplevel); -} -static void -toplevel_destroyed (GtkWidget *widget, - Drawer *drawer) -{ - drawer->toplevel = NULL; +/* Internal functions */ +/* event handlers */ - if (drawer->button) { - gtk_widget_destroy (drawer->button); - drawer->button = NULL; - } -} static void -destroy_drawer (GtkWidget *widget, - Drawer *drawer) +drawer_click (GtkWidget *widget, + Drawer *drawer) { - if (drawer->toplevel) { - gtk_widget_destroy (GTK_WIDGET (drawer->toplevel)); - drawer->toplevel = NULL; - } - - if (drawer->close_timeout_id) { - g_source_remove (drawer->close_timeout_id); - drawer->close_timeout_id = 0; - } + if (!panel_toplevel_get_is_hidden (drawer->toplevel)) + panel_toplevel_hide (drawer->toplevel, FALSE, -1); + else + panel_toplevel_unhide (drawer->toplevel); } static void drawer_focus_panel_widget (Drawer *drawer, - GtkDirectionType direction) + GtkDirectionType direction) { - PanelWidget *panel_widget; + PanelWidget *panel_widget; - panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); + panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); - gtk_window_present (GTK_WINDOW (drawer->toplevel)); - gtk_container_set_focus_child (GTK_CONTAINER (panel_widget), NULL); - gtk_widget_child_focus (GTK_WIDGET (panel_widget), direction); + gtk_window_present (GTK_WINDOW (drawer->toplevel)); + gtk_container_set_focus_child (GTK_CONTAINER (panel_widget), NULL); + gtk_widget_child_focus (GTK_WIDGET (panel_widget), direction); } static gboolean key_press_drawer (GtkWidget *widget, - GdkEventKey *event, - Drawer *drawer) + GdkEventKey *event, + Drawer *drawer) { - gboolean retval = TRUE; - GtkOrientation orient; - - if (event->state & gtk_accelerator_get_default_mod_mask ()) - return FALSE; - - orient = PANEL_WIDGET (gtk_widget_get_parent (drawer->button))->orient; - - switch (event->keyval) { - case GDK_KEY_Up: - case GDK_KEY_KP_Up: - if (orient == GTK_ORIENTATION_HORIZONTAL) { - if (!panel_toplevel_get_is_hidden (drawer->toplevel)) - drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD); - } else { - /* let default focus movement happen */ - retval = FALSE; - } - break; - case GDK_KEY_Left: - case GDK_KEY_KP_Left: - if (orient == GTK_ORIENTATION_VERTICAL) { - if (!panel_toplevel_get_is_hidden (drawer->toplevel)) - drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD); - } else { - /* let default focus movement happen */ - retval = FALSE; - } - break; - case GDK_KEY_Down: - case GDK_KEY_KP_Down: - if (orient == GTK_ORIENTATION_HORIZONTAL) { - if (!panel_toplevel_get_is_hidden (drawer->toplevel)) - drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD); - } else { - /* let default focus movement happen */ - retval = FALSE; - } - break; - case GDK_KEY_Right: - case GDK_KEY_KP_Right: - if (orient == GTK_ORIENTATION_VERTICAL) { - if (!panel_toplevel_get_is_hidden (drawer->toplevel)) - drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD); - } else { - /* let default focus movement happen */ - retval = FALSE; - } - break; - case GDK_KEY_Escape: - panel_toplevel_hide (drawer->toplevel, FALSE, -1); - break; - default: - retval = FALSE; - break; - } - - return retval; + gboolean retval = TRUE; + GtkOrientation orient; + + if (event->state & gtk_accelerator_get_default_mod_mask ()) + return FALSE; + + orient = PANEL_WIDGET (gtk_widget_get_parent (drawer->button))->orient; + + switch (event->keyval) { + case GDK_KEY_Up: + case GDK_KEY_KP_Up: + if (orient == GTK_ORIENTATION_HORIZONTAL) { + if (!panel_toplevel_get_is_hidden (drawer->toplevel)) + drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD); + } else { + /* let default focus movement happen */ + retval = FALSE; + } + break; + case GDK_KEY_Left: + case GDK_KEY_KP_Left: + if (orient == GTK_ORIENTATION_VERTICAL) { + if (!panel_toplevel_get_is_hidden (drawer->toplevel)) + drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD); + } else { + /* let default focus movement happen */ + retval = FALSE; + } + break; + case GDK_KEY_Down: + case GDK_KEY_KP_Down: + if (orient == GTK_ORIENTATION_HORIZONTAL) { + if (!panel_toplevel_get_is_hidden (drawer->toplevel)) + drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD); + } else { + /* let default focus movement happen */ + retval = FALSE; + } + break; + case GDK_KEY_Right: + case GDK_KEY_KP_Right: + if (orient == GTK_ORIENTATION_VERTICAL) { + if (!panel_toplevel_get_is_hidden (drawer->toplevel)) + drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD); + } else { + /* let default focus movement happen */ + retval = FALSE; + } + break; + case GDK_KEY_Escape: + panel_toplevel_hide (drawer->toplevel, FALSE, -1); + break; + default: + retval = FALSE; + break; + } + + return retval; } /* @@ -154,595 +135,615 @@ key_press_drawer (GtkWidget *widget, */ static gboolean key_press_drawer_widget (GtkWidget *widget, - GdkEventKey *event, - Drawer *drawer) + GdkEventKey *event, + Drawer *drawer) { - PanelWidget *panel_widget; + PanelWidget *panel_widget; - if (event->keyval != GDK_KEY_Escape) - return FALSE; + if (event->keyval != GDK_KEY_Escape) + return FALSE; - panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); + panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); - gtk_window_present (GTK_WINDOW (panel_widget->toplevel)); + gtk_window_present (GTK_WINDOW (panel_widget->toplevel)); - if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_SHIFT_MASK || - panel_toplevel_get_is_hidden (drawer->toplevel)) - return TRUE; + if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_SHIFT_MASK || + panel_toplevel_get_is_hidden (drawer->toplevel)) + return TRUE; - panel_toplevel_hide (drawer->toplevel, FALSE, -1); + panel_toplevel_hide (drawer->toplevel, FALSE, -1); - return TRUE; + return TRUE; } + /* drag and drop handlers */ + static void -drag_data_received_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time_, - Drawer *drawer) +drag_data_get_cb (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time, + Drawer *drawer) { - PanelWidget *panel_widget; + char *foo; - if (!panel_check_dnd_target_data (widget, context, &info, NULL)) { - gtk_drag_finish (context, FALSE, FALSE, time_); - return; - } + foo = g_strdup_printf ("DRAWER:%d", panel_find_applet_index (widget)); - panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); + gtk_selection_data_set (selection_data, gtk_selection_data_get_target (selection_data), 8, (guchar *) foo, strlen (foo)); - panel_receive_dnd_data ( - panel_widget, info, -1, selection_data, context, time_); + g_free (foo); } static gboolean drag_motion_cb (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - guint time_, - Drawer *drawer) + GdkDragContext *context, + int x, + int y, + guint time_, + Drawer *drawer) { - PanelWidget *panel_widget; - guint info = 0; + PanelWidget *panel_widget; + guint info = 0; - if (!panel_check_dnd_target_data (widget, context, &info, NULL)) - return FALSE; + if (!panel_check_dnd_target_data (widget, context, &info, NULL)) + return FALSE; - panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); + panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); - if (!panel_check_drop_forbidden (panel_widget, context, info, time_)) - return FALSE; + if (!panel_check_drop_forbidden (panel_widget, context, info, time_)) + return FALSE; - if (drawer->close_timeout_id) - g_source_remove (drawer->close_timeout_id); - drawer->close_timeout_id = 0; + if (drawer->close_timeout_id) + g_source_remove (drawer->close_timeout_id); - button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), TRUE); + drawer->close_timeout_id = 0; - if (panel_toplevel_get_is_hidden (drawer->toplevel)) { - panel_toplevel_unhide (drawer->toplevel); - drawer->opened_for_drag = TRUE; - } + button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), TRUE); - return TRUE; + if (panel_toplevel_get_is_hidden (drawer->toplevel)) { + panel_toplevel_unhide (drawer->toplevel); + drawer->opened_for_drag = TRUE; + } + + return TRUE; +} + +static gboolean +drag_drop_cb (GtkWidget *widget, + GdkDragContext *context, + int x, + int y, + guint time_, + Drawer *drawer) +{ + GdkAtom atom = NULL; + + if (!panel_check_dnd_target_data (widget, context, NULL, &atom)) + return FALSE; + + gtk_drag_get_data (widget, context, atom, time_); + + return TRUE; +} + +static void +drag_data_received_cb (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time_, + Drawer *drawer) +{ + PanelWidget *panel_widget; + + if (!panel_check_dnd_target_data (widget, context, &info, NULL)) { + gtk_drag_finish (context, FALSE, FALSE, time_); + return; + } + + panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); + + panel_receive_dnd_data (panel_widget, info, -1, selection_data, context, time_); } static gboolean close_drawer_in_idle (gpointer data) { - Drawer *drawer = (Drawer *) data; + Drawer *drawer = (Drawer *) data; - drawer->close_timeout_id = 0; + drawer->close_timeout_id = 0; - if (drawer->opened_for_drag) { - panel_toplevel_hide (drawer->toplevel, FALSE, -1); - drawer->opened_for_drag = FALSE; - } + if (drawer->opened_for_drag) { + panel_toplevel_hide (drawer->toplevel, FALSE, -1); + drawer->opened_for_drag = FALSE; + } - return FALSE; + return FALSE; } static void queue_drawer_close_for_drag (Drawer *drawer) { - if (!drawer->close_timeout_id) - drawer->close_timeout_id = - g_timeout_add_seconds (1, close_drawer_in_idle, drawer); + if (!drawer->close_timeout_id) + drawer->close_timeout_id = g_timeout_add_seconds (1, close_drawer_in_idle, drawer); } static void drag_leave_cb (GtkWidget *widget, - GdkDragContext *context, - guint time_, - Drawer *drawer) + GdkDragContext *context, + guint time_, + Drawer *drawer) { - queue_drawer_close_for_drag (drawer); + queue_drawer_close_for_drag (drawer); - button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), FALSE); + button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), FALSE); } -static gboolean -drag_drop_cb (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - guint time_, - Drawer *drawer) + /* load_drawer_applet handlers */ + +static void +drawer_button_size_allocated (GtkWidget *widget, + GtkAllocation *alloc, + Drawer *drawer) { - GdkAtom atom = NULL; + if (!gtk_widget_get_realized (widget)) + return; - if (!panel_check_dnd_target_data (widget, context, NULL, &atom)) - return FALSE; + gtk_widget_queue_resize (GTK_WIDGET (drawer->toplevel)); - gtk_drag_get_data (widget, context, atom, time_); + g_object_set_data (G_OBJECT (widget), "allocated", GINT_TO_POINTER (TRUE)); +} - return TRUE; +static gboolean +drawer_changes_enabled (void) +{ + return !panel_lockdown_get_locked_down (); } + /* gsettings handlers */ + static void -drag_data_get_cb (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - Drawer *drawer) +panel_drawer_custom_icon_changed (GSettings *settings, + gchar *key, + Drawer *drawer) { - char *foo; + g_return_if_fail (drawer != NULL); + g_return_if_fail (drawer->button != NULL); - foo = g_strdup_printf ("DRAWER:%d", panel_find_applet_index (widget)); + gboolean use_custom_icon = g_settings_get_boolean (settings, PANEL_OBJECT_USE_CUSTOM_ICON_KEY); + char *custom_icon = g_settings_get_string (settings, PANEL_OBJECT_CUSTOM_ICON_KEY); - gtk_selection_data_set (selection_data, - gtk_selection_data_get_target (selection_data), 8, (guchar *)foo, - strlen (foo)); + if (use_custom_icon && custom_icon != NULL && custom_icon [0] != '\0') { + button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), custom_icon); + } else { + button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), PANEL_ICON_DRAWER); + } - g_free (foo); + g_free (custom_icon); } static void -set_tooltip_and_name (Drawer *drawer, - const char *tooltip) +panel_drawer_tooltip_changed (GSettings *settings, + gchar *key, + Drawer *drawer) { - g_return_if_fail (drawer != NULL); - g_return_if_fail (drawer->toplevel != NULL); + gchar *tooltip = g_settings_get_string (settings, key); + set_tooltip_and_name (drawer, tooltip); + g_free (tooltip); +} + + /* destroy handlers */ - if (tooltip != NULL && tooltip [0] != '\0') { - panel_toplevel_set_name (drawer->toplevel, tooltip); - panel_util_set_tooltip_text (drawer->button, tooltip); - } +static void +toplevel_destroyed (GtkWidget *widget, + Drawer *drawer) +{ + drawer->toplevel = NULL; + + if (drawer->button) { + gtk_widget_destroy (drawer->button); + drawer->button = NULL; + } } -static Drawer * -create_drawer_applet (PanelToplevel *toplevel, - PanelToplevel *parent_toplevel, - const char *tooltip, - const char *custom_icon, - gboolean use_custom_icon, - PanelOrientation orientation) +static void +destroy_drawer (GtkWidget *widget, + Drawer *drawer) { - Drawer *drawer; - AtkObject *atk_obj; - - drawer = g_new0 (Drawer, 1); - - drawer->toplevel = toplevel; - - if (!use_custom_icon || !custom_icon || !custom_icon [0]) { - drawer->button = button_widget_new (PANEL_ICON_DRAWER, TRUE, - orientation); - } else { - drawer->button = button_widget_new (custom_icon, TRUE, - orientation); - } - - if (!drawer->button) { - g_free (drawer); - return NULL; - } - atk_obj = gtk_widget_get_accessible (drawer->button); - atk_object_set_name (atk_obj, _("Drawer")); - - set_tooltip_and_name (drawer, tooltip); - - gtk_drag_dest_set (drawer->button, 0, NULL, 0, 0); - - g_signal_connect (drawer->button, "drag_data_get", - G_CALLBACK (drag_data_get_cb), drawer); - g_signal_connect (drawer->button, "drag_data_received", - G_CALLBACK (drag_data_received_cb), drawer); - g_signal_connect (drawer->button, "drag_motion", - G_CALLBACK (drag_motion_cb), drawer); - g_signal_connect (drawer->button, "drag_leave", - G_CALLBACK (drag_leave_cb), drawer); - g_signal_connect (drawer->button, "drag_drop", - G_CALLBACK (drag_drop_cb), drawer); - - g_signal_connect (drawer->button, "clicked", - G_CALLBACK (drawer_click), drawer); - g_signal_connect (drawer->button, "destroy", - G_CALLBACK (destroy_drawer), drawer); - g_signal_connect (drawer->button, "key_press_event", - G_CALLBACK (key_press_drawer), drawer); - g_signal_connect (toplevel, "destroy", - G_CALLBACK (toplevel_destroyed), drawer); - - gtk_widget_show (drawer->button); - - g_signal_connect (drawer->toplevel, "key_press_event", - G_CALLBACK (key_press_drawer_widget), drawer); - - panel_toplevel_attach_to_widget ( - toplevel, parent_toplevel, GTK_WIDGET (drawer->button)); - - return drawer; + if (drawer->toplevel) { + gtk_widget_destroy (GTK_WIDGET (drawer->toplevel)); + drawer->toplevel = NULL; + } + + if (drawer->close_timeout_id) { + g_source_remove (drawer->close_timeout_id); + drawer->close_timeout_id = 0; + } } +static void +drawer_deletion_response (GtkWidget *dialog, + int response, + Drawer *drawer) +{ + if (response == GTK_RESPONSE_OK) + panel_profile_delete_object (drawer->info); + + gtk_widget_destroy (dialog); +} + +/* end event handlers */ + static PanelToplevel * -create_drawer_toplevel (const char *drawer_id, GSettings *settings) +create_drawer_toplevel (const char *drawer_id, + GSettings *settings) { - PanelToplevel *toplevel; - char *toplevel_id; + PanelToplevel *toplevel; + char *toplevel_id; - toplevel_id = panel_profile_find_new_id (PANEL_GSETTINGS_TOPLEVELS); - toplevel = panel_profile_load_toplevel (toplevel_id); + toplevel_id = panel_profile_find_new_id (PANEL_GSETTINGS_TOPLEVELS); + toplevel = panel_profile_load_toplevel (toplevel_id); - if (!toplevel) { - g_free (toplevel_id); - return NULL; - } + if (!toplevel) { + g_free (toplevel_id); + return NULL; + } - g_settings_set_string (settings, PANEL_OBJECT_ATTACHED_TOPLEVEL_ID_KEY, toplevel_id); - g_free (toplevel_id); + g_settings_set_string (settings, PANEL_OBJECT_ATTACHED_TOPLEVEL_ID_KEY, toplevel_id); + g_free (toplevel_id); - panel_profile_set_toplevel_enable_buttons (toplevel, TRUE); - panel_profile_set_toplevel_enable_arrows (toplevel, TRUE); + panel_profile_set_toplevel_enable_buttons (toplevel, TRUE); + panel_profile_set_toplevel_enable_arrows (toplevel, TRUE); - return toplevel; + return toplevel; } static void -drawer_button_size_allocated (GtkWidget *widget, - GtkAllocation *alloc, - Drawer *drawer) +set_tooltip_and_name (Drawer *drawer, + const char *tooltip) { - if (!gtk_widget_get_realized (widget)) - return; - - gtk_widget_queue_resize (GTK_WIDGET (drawer->toplevel)); + g_return_if_fail (drawer != NULL); + g_return_if_fail (drawer->toplevel != NULL); - g_object_set_data (G_OBJECT (widget), "allocated", GINT_TO_POINTER (TRUE)); + if (tooltip != NULL && tooltip [0] != '\0') { + panel_toplevel_set_name (drawer->toplevel, tooltip); + panel_util_set_tooltip_text (drawer->button, tooltip); + } } -static void -panel_drawer_custom_icon_changed (GSettings *settings, - gchar *key, - Drawer *drawer) +static Drawer * +create_drawer_applet (PanelToplevel *toplevel, + PanelToplevel *parent_toplevel, + const char *tooltip, + const char *custom_icon, + gboolean use_custom_icon, + PanelOrientation orientation) { - g_return_if_fail (drawer != NULL); - g_return_if_fail (drawer->button != NULL); + Drawer *drawer; + AtkObject *atk_obj; - gboolean use_custom_icon = g_settings_get_boolean (settings, PANEL_OBJECT_USE_CUSTOM_ICON_KEY); - char *custom_icon = g_settings_get_string (settings, PANEL_OBJECT_CUSTOM_ICON_KEY); + drawer = g_new0 (Drawer, 1); - if (use_custom_icon && custom_icon != NULL && custom_icon [0] != '\0') { - button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), custom_icon); - } else { - button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), PANEL_ICON_DRAWER); - } + drawer->toplevel = toplevel; - g_free (custom_icon); -} + if (!use_custom_icon || !custom_icon || !custom_icon [0]) { + drawer->button = button_widget_new (PANEL_ICON_DRAWER, TRUE, orientation); + } else { + drawer->button = button_widget_new (custom_icon, TRUE, orientation); + } -static void -panel_drawer_tooltip_changed (GSettings *settings, - gchar *key, - Drawer *drawer) -{ - gchar *tooltip = g_settings_get_string (settings, key); - set_tooltip_and_name (drawer, tooltip); - g_free (tooltip); + if (!drawer->button) { + g_free (drawer); + return NULL; + } + + atk_obj = gtk_widget_get_accessible (drawer->button); + atk_object_set_name (atk_obj, _("Drawer")); + + set_tooltip_and_name (drawer, tooltip); + + g_signal_connect (drawer->button, "clicked", G_CALLBACK (drawer_click), drawer); + g_signal_connect (drawer->button, "key_press_event", G_CALLBACK (key_press_drawer), drawer); + g_signal_connect (drawer->toplevel, "key_press_event", G_CALLBACK (key_press_drawer_widget), drawer); + + + gtk_drag_dest_set (drawer->button, 0, NULL, 0, 0); + + g_signal_connect (drawer->button, "drag_data_get", G_CALLBACK (drag_data_get_cb), drawer); + g_signal_connect (drawer->button, "drag_motion", G_CALLBACK (drag_motion_cb), drawer); + g_signal_connect (drawer->button, "drag_drop", G_CALLBACK (drag_drop_cb), drawer); + g_signal_connect (drawer->button, "drag_data_received", G_CALLBACK (drag_data_received_cb), drawer); + g_signal_connect (drawer->button, "drag_leave", G_CALLBACK (drag_leave_cb), drawer); + + + g_signal_connect (drawer->button, "destroy", G_CALLBACK (destroy_drawer), drawer); + g_signal_connect (drawer->toplevel, "destroy", G_CALLBACK (toplevel_destroyed), drawer); + + gtk_widget_show (drawer->button); + + panel_toplevel_attach_to_widget (drawer->toplevel, parent_toplevel, GTK_WIDGET (drawer->button)); + + return drawer; } static void panel_drawer_connect_to_gsettings (Drawer *drawer) { - g_signal_connect (drawer->info->settings, - "changed::" PANEL_OBJECT_USE_CUSTOM_ICON_KEY, - G_CALLBACK (panel_drawer_custom_icon_changed), - drawer); - g_signal_connect (drawer->info->settings, - "changed::" PANEL_OBJECT_CUSTOM_ICON_KEY, - G_CALLBACK (panel_drawer_custom_icon_changed), - drawer); - g_signal_connect (drawer->info->settings, - "changed::" PANEL_OBJECT_TOOLTIP_KEY, - G_CALLBACK (panel_drawer_tooltip_changed), - drawer); -} - -static gboolean -drawer_changes_enabled (void) -{ - return !panel_lockdown_get_locked_down (); + g_signal_connect (drawer->info->settings, + "changed::" PANEL_OBJECT_USE_CUSTOM_ICON_KEY, + G_CALLBACK (panel_drawer_custom_icon_changed), + drawer); + + g_signal_connect (drawer->info->settings, + "changed::" PANEL_OBJECT_CUSTOM_ICON_KEY, + G_CALLBACK (panel_drawer_custom_icon_changed), + drawer); + + g_signal_connect (drawer->info->settings, + "changed::" PANEL_OBJECT_TOOLTIP_KEY, + G_CALLBACK (panel_drawer_tooltip_changed), + drawer); } static void load_drawer_applet (char *toplevel_id, - GSettings *settings, - const char *custom_icon, - gboolean use_custom_icon, - const char *tooltip, - PanelToplevel *parent_toplevel, - gboolean locked, - int pos, - gboolean exactpos, - const char *id) + GSettings *settings, + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip, + PanelToplevel *parent_toplevel, + gboolean locked, + int pos, + gboolean exactpos, + const char *id) { - PanelOrientation orientation; - PanelToplevel *toplevel = NULL; - Drawer *drawer = NULL; - PanelWidget *panel_widget; - - orientation = panel_toplevel_get_orientation (parent_toplevel); - - if (toplevel_id) - toplevel = panel_profile_get_toplevel_by_id (toplevel_id); - - if (!toplevel) - toplevel = create_drawer_toplevel (id, settings); - - if (toplevel) { - panel_toplevel_hide (toplevel, FALSE, -1); - drawer = create_drawer_applet (toplevel, - parent_toplevel, - tooltip, - custom_icon, - use_custom_icon, - orientation); - } - - if (!drawer) - return; - - panel_widget = panel_toplevel_get_panel_widget (parent_toplevel); - - drawer->info = mate_panel_applet_register (drawer->button, drawer, - (GDestroyNotify) g_free, - panel_widget, - locked, pos, exactpos, - PANEL_OBJECT_DRAWER, id); - - if (!drawer->info) { - gtk_widget_destroy (GTK_WIDGET (toplevel)); - return; - } - - g_signal_connect_after (drawer->button, "size_allocate", - G_CALLBACK (drawer_button_size_allocated), drawer); - - panel_widget_add_forbidden (panel_toplevel_get_panel_widget (drawer->toplevel)); - panel_widget_set_applet_expandable (panel_widget, GTK_WIDGET (drawer->button), FALSE, TRUE); - panel_widget_set_applet_size_constrained (panel_widget, GTK_WIDGET (drawer->button), TRUE); - - mate_panel_applet_add_callback (drawer->info, - "add", - "list-add", - _("_Add to Drawer..."), - drawer_changes_enabled); - - mate_panel_applet_add_callback (drawer->info, - "properties", - "document-properties", - _("_Properties"), - drawer_changes_enabled); - - mate_panel_applet_add_callback (drawer->info, - "help", - "help-browser", - _("_Help"), - NULL); - - panel_drawer_connect_to_gsettings (drawer); + PanelOrientation orientation; + PanelToplevel *toplevel = NULL; + Drawer *drawer = NULL; + PanelWidget *panel_widget; + + orientation = panel_toplevel_get_orientation (parent_toplevel); + + if (toplevel_id) + toplevel = panel_profile_get_toplevel_by_id (toplevel_id); + + if (!toplevel) + toplevel = create_drawer_toplevel (id, settings); + + if (toplevel) { + panel_toplevel_hide (toplevel, FALSE, -1); + drawer = create_drawer_applet (toplevel, + parent_toplevel, + tooltip, + custom_icon, + use_custom_icon, + orientation); + } + + if (!drawer) + return; + + panel_widget = panel_toplevel_get_panel_widget (parent_toplevel); + + drawer->info = mate_panel_applet_register (drawer->button, drawer, + (GDestroyNotify) g_free, + panel_widget, + locked, pos, exactpos, + PANEL_OBJECT_DRAWER, id); + + if (!drawer->info) { + gtk_widget_destroy (GTK_WIDGET (toplevel)); + return; + } + + g_signal_connect_after (drawer->button, "size_allocate", G_CALLBACK (drawer_button_size_allocated), drawer); + + panel_widget_add_forbidden (panel_toplevel_get_panel_widget (drawer->toplevel)); + panel_widget_set_applet_expandable (panel_widget, GTK_WIDGET (drawer->button), FALSE, TRUE); + panel_widget_set_applet_size_constrained (panel_widget, GTK_WIDGET (drawer->button), TRUE); + + mate_panel_applet_add_callback (drawer->info, + "add", + "list-add", + _("_Add to Drawer..."), + drawer_changes_enabled); + + mate_panel_applet_add_callback (drawer->info, + "properties", + "document-properties", + _("_Properties"), + drawer_changes_enabled); + + mate_panel_applet_add_callback (drawer->info, + "help", + "help-browser", + _("_Help"), + NULL); + + panel_drawer_connect_to_gsettings (drawer); } static void panel_drawer_prepare (const char *drawer_id, - const char *custom_icon, - gboolean use_custom_icon, - const char *tooltip, - char **attached_toplevel_id) + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip, + char **attached_toplevel_id) { - GSettings *settings; - char *path; - - path = g_strdup_printf ("%s%s/", PANEL_OBJECT_PATH, drawer_id); - settings = g_settings_new_with_path (PANEL_OBJECT_SCHEMA, path); - g_free (path); + GSettings *settings; + char *path; + + path = g_strdup_printf ("%s%s/", PANEL_OBJECT_PATH, drawer_id); + settings = g_settings_new_with_path (PANEL_OBJECT_SCHEMA, path); + g_free (path); - if (tooltip) { - g_settings_set_string (settings, PANEL_OBJECT_TOOLTIP_KEY, tooltip); - } + if (tooltip) { + g_settings_set_string (settings, PANEL_OBJECT_TOOLTIP_KEY, tooltip); + } - g_settings_set_boolean (settings, PANEL_OBJECT_USE_CUSTOM_ICON_KEY, use_custom_icon); + g_settings_set_boolean (settings, PANEL_OBJECT_USE_CUSTOM_ICON_KEY, use_custom_icon); - if (custom_icon) { - g_settings_set_string (settings, PANEL_OBJECT_CUSTOM_ICON_KEY, custom_icon); - } + if (custom_icon) { + g_settings_set_string (settings, PANEL_OBJECT_CUSTOM_ICON_KEY, custom_icon); + } - if (attached_toplevel_id) { - char *toplevel_id; - char *toplevel_path; - GSettings *toplevel_settings; + if (attached_toplevel_id) { + char *toplevel_id; + char *toplevel_path; + GSettings *toplevel_settings; - toplevel_id = panel_profile_find_new_id (PANEL_GSETTINGS_TOPLEVELS); + toplevel_id = panel_profile_find_new_id (PANEL_GSETTINGS_TOPLEVELS); - toplevel_path = g_strdup_printf (PANEL_TOPLEVEL_PATH "%s/", - toplevel_id); + toplevel_path = g_strdup_printf (PANEL_TOPLEVEL_PATH "%s/", toplevel_id); - toplevel_settings = g_settings_new_with_path (PANEL_TOPLEVEL_SCHEMA, toplevel_path); + toplevel_settings = g_settings_new_with_path (PANEL_TOPLEVEL_SCHEMA, toplevel_path); - g_settings_set_string (settings, PANEL_OBJECT_ATTACHED_TOPLEVEL_ID_KEY, toplevel_id); - g_settings_set_boolean (toplevel_settings, PANEL_TOPLEVEL_ENABLE_BUTTONS_KEY, TRUE); - g_settings_set_boolean (toplevel_settings, PANEL_TOPLEVEL_ENABLE_ARROWS_KEY, TRUE); + g_settings_set_string (settings, PANEL_OBJECT_ATTACHED_TOPLEVEL_ID_KEY, toplevel_id); + g_settings_set_boolean (toplevel_settings, PANEL_TOPLEVEL_ENABLE_BUTTONS_KEY, TRUE); + g_settings_set_boolean (toplevel_settings, PANEL_TOPLEVEL_ENABLE_ARROWS_KEY, TRUE); - *attached_toplevel_id = toplevel_id; + *attached_toplevel_id = toplevel_id; - g_object_unref (toplevel_settings); - g_free (toplevel_path); - } - g_object_unref (settings); + g_object_unref (toplevel_settings); + g_free (toplevel_path); + } + g_object_unref (settings); } +/* API */ + void panel_drawer_create (PanelToplevel *toplevel, - int position, - const char *custom_icon, - gboolean use_custom_icon, - const char *tooltip) + int position, + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip) { - char *id; + char *id; - id = panel_profile_prepare_object (PANEL_OBJECT_DRAWER, toplevel, position, FALSE); + id = panel_profile_prepare_object (PANEL_OBJECT_DRAWER, toplevel, position, FALSE); - panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, NULL); + panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, NULL); - panel_profile_add_to_list (PANEL_GSETTINGS_OBJECTS, id); + panel_profile_add_to_list (PANEL_GSETTINGS_OBJECTS, id); - g_free (id); + g_free (id); } char * panel_drawer_create_with_id (const char *toplevel_id, - int position, - const char *custom_icon, - gboolean use_custom_icon, - const char *tooltip) + int position, + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip) { - char *id; - char *attached_toplevel_id = NULL; + char *id; + char *attached_toplevel_id = NULL; - id = panel_profile_prepare_object_with_id (PANEL_OBJECT_DRAWER, toplevel_id, position, FALSE); + id = panel_profile_prepare_object_with_id (PANEL_OBJECT_DRAWER, toplevel_id, position, FALSE); - panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, &attached_toplevel_id); + panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, &attached_toplevel_id); - panel_profile_add_to_list (PANEL_GSETTINGS_OBJECTS, id); + panel_profile_add_to_list (PANEL_GSETTINGS_OBJECTS, id); - g_free (id); + g_free (id); - return attached_toplevel_id; + return attached_toplevel_id; } void drawer_load_from_gsettings (PanelWidget *panel_widget, - gboolean locked, - gint position, - const char *id) + gboolean locked, + gint position, + const char *id) { - gboolean use_custom_icon; - char *toplevel_id; - char *custom_icon; - char *tooltip; - gchar *path; - GSettings *settings; - - g_return_if_fail (panel_widget != NULL); - g_return_if_fail (id != NULL); - - path = g_strdup_printf ("%s%s/", PANEL_OBJECT_PATH, id); - settings = g_settings_new_with_path (PANEL_OBJECT_SCHEMA, path); - g_free (path); - - toplevel_id = g_settings_get_string (settings, PANEL_OBJECT_ATTACHED_TOPLEVEL_ID_KEY); - - panel_profile_load_toplevel (toplevel_id); - - use_custom_icon = g_settings_get_boolean (settings, PANEL_OBJECT_USE_CUSTOM_ICON_KEY); - custom_icon = g_settings_get_string (settings, PANEL_OBJECT_CUSTOM_ICON_KEY); - - tooltip = g_settings_get_string (settings, PANEL_OBJECT_TOOLTIP_KEY); - - load_drawer_applet (toplevel_id, - settings, - custom_icon, - use_custom_icon, - tooltip, - panel_widget->toplevel, - locked, - position, - TRUE, - id); - - g_free (toplevel_id); - g_free (custom_icon); - g_free (tooltip); + gboolean use_custom_icon; + char *toplevel_id; + char *custom_icon; + char *tooltip; + gchar *path; + GSettings *settings; + + g_return_if_fail (panel_widget != NULL); + g_return_if_fail (id != NULL); + + path = g_strdup_printf ("%s%s/", PANEL_OBJECT_PATH, id); + settings = g_settings_new_with_path (PANEL_OBJECT_SCHEMA, path); + g_free (path); + + toplevel_id = g_settings_get_string (settings, PANEL_OBJECT_ATTACHED_TOPLEVEL_ID_KEY); + + panel_profile_load_toplevel (toplevel_id); + + use_custom_icon = g_settings_get_boolean (settings, PANEL_OBJECT_USE_CUSTOM_ICON_KEY); + custom_icon = g_settings_get_string (settings, PANEL_OBJECT_CUSTOM_ICON_KEY); + + tooltip = g_settings_get_string (settings, PANEL_OBJECT_TOOLTIP_KEY); + + load_drawer_applet (toplevel_id, + settings, + custom_icon, + use_custom_icon, + tooltip, + panel_widget->toplevel, + locked, + position, + TRUE, + id); + + g_free (toplevel_id); + g_free (custom_icon); + g_free (tooltip); } void panel_drawer_set_dnd_enabled (Drawer *drawer, - gboolean dnd_enabled) + gboolean dnd_enabled) { - if (dnd_enabled) { - static GtkTargetEntry dnd_targets[] = { - { "application/x-mate-panel-applet-internal", 0, 0 } - }; - - gtk_widget_set_has_window (drawer->button, TRUE); - gtk_drag_source_set (drawer->button, - GDK_BUTTON1_MASK, - dnd_targets, 1, - GDK_ACTION_MOVE); - //FIXME: we're forgetting the use_custom_icon case, here - gtk_drag_source_set_icon_name (drawer->button, - button_widget_get_icon_name (BUTTON_WIDGET (drawer->button))); - - gtk_widget_set_has_window (drawer->button, FALSE); - - } else - gtk_drag_source_unset (drawer->button); -} - -static void -drawer_deletion_response (GtkWidget *dialog, - int response, - Drawer *drawer) -{ - if (response == GTK_RESPONSE_OK) - panel_profile_delete_object (drawer->info); - - gtk_widget_destroy (dialog); + if (dnd_enabled) { + static GtkTargetEntry dnd_targets[] = { + { "application/x-mate-panel-applet-internal", 0, 0 } + }; + + gtk_widget_set_has_window (drawer->button, TRUE); + gtk_drag_source_set (drawer->button, + GDK_BUTTON1_MASK, + dnd_targets, 1, + GDK_ACTION_MOVE); + //FIXME: we're forgetting the use_custom_icon case, here + gtk_drag_source_set_icon_name (drawer->button, button_widget_get_icon_name (BUTTON_WIDGET (drawer->button))); + + gtk_widget_set_has_window (drawer->button, FALSE); + + } else + gtk_drag_source_unset (drawer->button); } void drawer_query_deletion (Drawer *drawer) { - GtkWidget *dialog; + GtkWidget *dialog; - if (drawer->toplevel) { - PanelWidget *panel_widget; + if (drawer->toplevel) { + PanelWidget *panel_widget; - panel_widget = panel_toplevel_get_panel_widget ( - drawer->toplevel); + panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel); - if (!panel_global_config_get_confirm_panel_remove () || - !g_list_length (panel_widget->applet_list)) { - panel_profile_delete_object (drawer->info); - return; - } + if (!panel_global_config_get_confirm_panel_remove () || + !g_list_length (panel_widget->applet_list)) { + panel_profile_delete_object (drawer->info); + return; + } - dialog = panel_deletion_dialog (drawer->toplevel); + dialog = panel_deletion_dialog (drawer->toplevel); - g_signal_connect (dialog, "response", - G_CALLBACK (drawer_deletion_response), - drawer); + g_signal_connect (dialog, "response", G_CALLBACK (drawer_deletion_response), drawer); - g_signal_connect_object (drawer->toplevel, "destroy", - G_CALLBACK (gtk_widget_destroy), - dialog, - G_CONNECT_SWAPPED); + g_signal_connect_object (drawer->toplevel, "destroy", G_CALLBACK (gtk_widget_destroy), dialog, G_CONNECT_SWAPPED); - gtk_widget_show_all (dialog); - } + gtk_widget_show_all (dialog); + } } diff --git a/mate-panel/drawer.h b/mate-panel/drawer.h index 4365befc..67c7c6d1 100644 --- a/mate-panel/drawer.h +++ b/mate-panel/drawer.h @@ -7,39 +7,44 @@ extern "C" { #endif + typedef struct { - char *tooltip; + char *tooltip; - PanelToplevel *toplevel; - GtkWidget *button; + PanelToplevel *toplevel; + GtkWidget *button; - gboolean opened_for_drag; - guint close_timeout_id; + gboolean opened_for_drag; + guint close_timeout_id; - AppletInfo *info; + AppletInfo *info; } Drawer; -void panel_drawer_create (PanelToplevel *toplevel, - int position, - const char *custom_icon, - gboolean use_custom_icon, - const char *tooltip); -char *panel_drawer_create_with_id (const char *toplevel_id, - int position, - const char *custom_icon, - gboolean use_custom_icon, - const char *tooltip); +/* API */ + +void panel_drawer_create (PanelToplevel *toplevel, + int position, + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip); + +char *panel_drawer_create_with_id (const char *toplevel_id, + int position, + const char *custom_icon, + gboolean use_custom_icon, + const char *tooltip); + +void drawer_load_from_gsettings (PanelWidget *panel_widget, + gboolean locked, + gint position, + const char *id); -void panel_drawer_set_dnd_enabled (Drawer *drawer, - gboolean dnd_enabled); +void panel_drawer_set_dnd_enabled (Drawer *drawer, + gboolean dnd_enabled); -void drawer_load_from_gsettings (PanelWidget *panel_widget, - gboolean locked, - gint position, - const char *id); +void drawer_query_deletion (Drawer *drawer); -void drawer_query_deletion (Drawer *drawer); #ifdef __cplusplus } diff --git a/mate-panel/panel-toplevel.c b/mate-panel/panel-toplevel.c index d6d8fda7..19d14b3c 100644 --- a/mate-panel/panel-toplevel.c +++ b/mate-panel/panel-toplevel.c @@ -3666,10 +3666,15 @@ panel_toplevel_hide (PanelToplevel *toplevel, panel_toplevel_update_hide_buttons (toplevel); } - if (toplevel->priv->animate && gtk_widget_get_realized (GTK_WIDGET (toplevel))) + if (toplevel->priv->animate && gtk_widget_get_realized (GTK_WIDGET (toplevel))) { panel_toplevel_start_animation (toplevel); - else if (toplevel->priv->attached) + } + + /* if the toplevel is attached (-> drawer), hide it after the animation + * this hides the hide button properly as well */ + if (toplevel->priv->attached) { gtk_widget_hide (GTK_WIDGET (toplevel)); + } gtk_widget_queue_resize (GTK_WIDGET (toplevel)); } @@ -3714,10 +3719,15 @@ panel_toplevel_unhide (PanelToplevel *toplevel) if (toplevel->priv->attach_toplevel) panel_toplevel_push_autohide_disabler (toplevel->priv->attach_toplevel); - if (toplevel->priv->animate && gtk_widget_get_realized (GTK_WIDGET (toplevel))) + if (toplevel->priv->animate && gtk_widget_get_realized (GTK_WIDGET (toplevel))) { panel_toplevel_start_animation (toplevel); - else if (toplevel->priv->attached) + } + + /* if the toplevel is attached (-> drawer), unhide it after the animation + * (same as for hide) */ + if (toplevel->priv->attached) { gtk_widget_show (GTK_WIDGET (toplevel)); + } gtk_widget_queue_resize (GTK_WIDGET (toplevel)); -- cgit v1.2.1