From 566165c32861bca7b565f4e226a9e78fa85fb3d9 Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 25 Jan 2015 17:06:19 +0100 Subject: fix dock applet resizing and other issues --- libmdock/mdock-item-menu.c | 1 - libmdock/mdock-item.c | 29 ++++++++++++--- libmdock/mdock-widget.c | 25 ++++++++----- libmdock/mdock-widget.h | 3 ++ mate-applet/mdock-mate-panel-applet.c | 67 +++++++++++++++++++++++++++-------- 5 files changed, 98 insertions(+), 27 deletions(-) diff --git a/libmdock/mdock-item-menu.c b/libmdock/mdock-item-menu.c index 484277b..39495af 100644 --- a/libmdock/mdock-item-menu.c +++ b/libmdock/mdock-item-menu.c @@ -304,7 +304,6 @@ mdock_item_menu_constructed(GObject *object) #ifdef HAVE_ZEITGEIST g_signal_connect(self, "map-event", G_CALLBACK(handle_menu_map), self); - refresh_recent_menu(self); #endif } diff --git a/libmdock/mdock-item.c b/libmdock/mdock-item.c index 2dd1611..aa3045f 100644 --- a/libmdock/mdock-item.c +++ b/libmdock/mdock-item.c @@ -17,6 +17,7 @@ * along with MDock. If not, see . */ +#include #include "mdock-item.h" #define MDOCK_ITEM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), MDOCK_TYPE_ITEM, MDockItemPrivate)) @@ -98,16 +99,15 @@ static void mdock_item_realize(GtkWidget *widget) widget->window = gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, attributes_mask); + gdk_window_set_back_pixmap(widget->window, NULL, TRUE); gdk_window_set_user_data(widget->window, widget); gtk_widget_set_realized(widget, TRUE); widget->style = gtk_style_attach(widget->style, widget->window); - gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL); } static void mdock_item_size_request(GtkWidget *widget, GtkRequisition *requisition) { - MDockItem *self = MDOCK_ITEM(widget); requisition->width = requisition->height = REQUISITION_ICON_SIZE; } @@ -115,8 +115,8 @@ static void mdock_item_size_allocate(GtkWidget *widget, GtkAllocation *allocatio { MDockItem *self = MDOCK_ITEM(widget); self->priv->icon_size = MIN(allocation->width, allocation->height); - mdock_item_update_icon(self); GTK_WIDGET_CLASS(mdock_item_parent_class)->size_allocate(widget, allocation); + mdock_item_update_icon(self); } static gboolean mdock_item_expose(GtkWidget *widget, GdkEventExpose *event) @@ -125,8 +125,19 @@ static gboolean mdock_item_expose(GtkWidget *widget, GdkEventExpose *event) cairo_t *cr = gdk_cairo_create(widget->window); if (self->priv->icon) { + cairo_save(cr); gdk_cairo_set_source_pixbuf(cr, self->priv->icon, 0, 0); cairo_paint(cr); + cairo_restore(cr); + } + if (self->priv->windows) { + double circle_radius = self->priv->icon_size / 8.0; + cairo_save(cr); + cairo_set_source_rgba(cr, 0.0, 0.0, 0.2, 0.6); + cairo_translate(cr, self->priv->icon_size / 2.0, self->priv->icon_size - circle_radius / 2.0); + cairo_arc(cr, 0, 0, circle_radius, 0, 2 * M_PI); + cairo_fill(cr); + cairo_restore(cr); } cairo_destroy(cr); @@ -198,7 +209,7 @@ static void mdock_item_init(MDockItem *self) { self->priv = MDOCK_ITEM_GET_PRIVATE (self); self->priv->pinned = FALSE; - self->priv->icon_size = 48; + self->priv->icon_size = REQUISITION_ICON_SIZE; gtk_widget_add_events(GTK_WIDGET(self), GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); @@ -341,6 +352,11 @@ GdkPixbuf *mdock_item_get_icon_pixbuf(MDockItem *self) void mdock_item_add_window(MDockItem *self, WnckWindow *window) { + if (!self->priv->windows) { + // If there were no windows before adding this one, + // we want to redraw in order to get the "active" indicator. + gtk_widget_queue_draw(GTK_WIDGET(self)); + } self->priv->windows = g_list_append(self->priv->windows, window); if (!self->priv->icon) { mdock_item_update_icon(self); @@ -354,6 +370,11 @@ void mdock_item_remove_window(MDockItem *self, WnckWindow *window) if (self->priv->last_active == window) { self->priv->last_active = NULL; } + if (self->priv->windows) { + // If there are no windows left, + // we want to redraw in order to remove the "active" indicator. + gtk_widget_queue_draw(GTK_WIDGET(self)); + } g_object_notify_by_pspec(G_OBJECT(self), obj_properties[PROP_N_WINDOWS]); } diff --git a/libmdock/mdock-widget.c b/libmdock/mdock-widget.c index cdb942e..6507fbb 100644 --- a/libmdock/mdock-widget.c +++ b/libmdock/mdock-widget.c @@ -33,6 +33,7 @@ #include #endif +#define POPUP_MOVE_TIMEOUT 100 #define POPUP_SHOW_TIMEOUT 200 #define POPUP_HIDE_TIMEOUT 500 @@ -413,7 +414,8 @@ static gboolean handle_popup_timer(gpointer user_data) MDockWidget *self = MDOCK_WIDGET(user_data); if (self->priv->current_popup_item) { hide_item_popup(self); - } else if (self->priv->current_pointed_item) { + } + if (self->priv->current_pointed_item) { show_item_popup(self, self->priv->current_pointed_item); } @@ -423,16 +425,14 @@ static gboolean handle_popup_timer(gpointer user_data) static gboolean handle_item_enter(MDockWidget *self, GdkEventCrossing *event, MDockItem *item) { - g_debug("Item enter"); + g_warn_if_fail(!self->priv->current_pointed_item); self->priv->current_pointed_item = item; if (self->priv->current_popup_item) { if (self->priv->popup_timer) { g_source_remove(self->priv->popup_timer); self->priv->popup_timer = 0; } - hide_item_popup(self); - show_item_popup(self, item); - + self->priv->popup_timer = g_timeout_add(POPUP_MOVE_TIMEOUT, handle_popup_timer, self); } else if (!self->priv->popup_timer) { self->priv->popup_timer = g_timeout_add(POPUP_SHOW_TIMEOUT, handle_popup_timer, self); } @@ -441,7 +441,6 @@ static gboolean handle_item_enter(MDockWidget *self, GdkEventCrossing *event, MD static gboolean handle_item_leave(MDockWidget *self, GdkEventCrossing *event, MDockItem *item) { - g_debug("Item leave"); g_warn_if_fail(self->priv->current_pointed_item == item); g_warn_if_fail(!self->priv->current_popup_item || self->priv->current_pointed_item == item); self->priv->current_pointed_item = NULL; @@ -454,7 +453,7 @@ static gboolean handle_item_leave(MDockWidget *self, GdkEventCrossing *event, MD static gboolean handle_item_selector_enter(MDockWidget *self, GdkEventCrossing *event, MDockItemWindowSelector *selector) { g_debug("Item selector enter %d", event->detail); - if (event->detail != GDK_NOTIFY_NONLINEAR) return FALSE; + if (event->detail == GDK_NOTIFY_INFERIOR) return FALSE; g_warn_if_fail(self->priv->current_popup_item); if (self->priv->popup_timer) { g_source_remove(self->priv->popup_timer); @@ -466,7 +465,7 @@ static gboolean handle_item_selector_enter(MDockWidget *self, GdkEventCrossing * static gboolean handle_item_selector_leave(MDockWidget *self, GdkEventCrossing *event, MDockItemWindowSelector *selector) { g_debug("Item selector leave %d", event->detail); - if (event->detail != GDK_NOTIFY_NONLINEAR) return FALSE; + if (event->detail == GDK_NOTIFY_INFERIOR) return FALSE; g_warn_if_fail(self->priv->current_popup_item); if (!self->priv->popup_timer) { self->priv->popup_timer = g_timeout_add(POPUP_HIDE_TIMEOUT, handle_popup_timer, self); @@ -815,7 +814,17 @@ static void mdock_widget_class_init(MDockWidgetClass *klass) g_type_class_add_private(klass, sizeof(MDockWidgetPrivate)); } +gint mdock_widget_get_n_items(MDockWidget *self) +{ + return g_sequence_get_length(self->priv->items); +} + GtkWidget *mdock_widget_new(void) { return GTK_WIDGET(g_object_new(MDOCK_TYPE_WIDGET, NULL)); } + +GtkWidget *mdock_widget_new_with_settings_path(const gchar *path) +{ + return GTK_WIDGET(g_object_new(MDOCK_TYPE_WIDGET, "settings-path", path, NULL)); +} diff --git a/libmdock/mdock-widget.h b/libmdock/mdock-widget.h index 00ad496..2771095 100644 --- a/libmdock/mdock-widget.h +++ b/libmdock/mdock-widget.h @@ -49,7 +49,10 @@ struct _MDockWidgetClass GType mdock_widget_get_type(void); +gint mdock_widget_get_n_items(MDockWidget *widget); + GtkWidget *mdock_widget_new(void); +GtkWidget *mdock_widget_new_with_settings_path(const gchar *path); G_END_DECLS diff --git a/mate-applet/mdock-mate-panel-applet.c b/mate-applet/mdock-mate-panel-applet.c index 7079c27..ba18f43 100644 --- a/mate-applet/mdock-mate-panel-applet.c +++ b/mate-applet/mdock-mate-panel-applet.c @@ -51,36 +51,63 @@ static const GtkActionEntry menu_verbs[] = { G_CALLBACK (display_about_dialog) } }; -static gboolean transform_applet_orient_to_orientation(GBinding *binding, const GValue *from_value, GValue *to_value, gpointer user_data) +static inline GtkOrientation applet_orient_to_orientation(MatePanelAppletOrient orient) { - MatePanelAppletOrient orient = g_value_get_enum(from_value); switch (orient) { case MATE_PANEL_APPLET_ORIENT_DOWN: case MATE_PANEL_APPLET_ORIENT_UP: - g_value_set_enum(to_value, GTK_ORIENTATION_HORIZONTAL); - break; + return GTK_ORIENTATION_HORIZONTAL; case MATE_PANEL_APPLET_ORIENT_LEFT: case MATE_PANEL_APPLET_ORIENT_RIGHT: - g_value_set_enum(to_value, GTK_ORIENTATION_VERTICAL); - break; + return GTK_ORIENTATION_VERTICAL; + default: + g_return_val_if_reached(GTK_ORIENTATION_HORIZONTAL); } } +static gboolean transform_applet_orient_to_orientation(GBinding *binding, const GValue *from_value, GValue *to_value, gpointer user_data) +{ + MatePanelAppletOrient orient = g_value_get_uint(from_value); + g_value_set_enum(to_value, applet_orient_to_orientation(orient)); +} + +static GtkOrientation mdock_mate_panel_applet_get_orientation(MDockMatePanelApplet *self) +{ + MatePanelAppletOrient orient = mate_panel_applet_get_orient(MATE_PANEL_APPLET(self)); + return applet_orient_to_orientation(orient); +} + static void mdock_mate_panel_applet_size_allocate(GtkWidget *widget, GtkAllocation *allocation) { MDockMatePanelApplet *self = MDOCK_MATE_PANEL_APPLET(widget); - if (self->dock) { - gtk_widget_size_allocate(GTK_WIDGET(self->dock), allocation); - } GTK_WIDGET_CLASS(mdock_mate_panel_applet_parent_class)->size_allocate(widget, allocation); + gtk_widget_size_allocate(GTK_WIDGET(self->dock), allocation); } static void mdock_mate_panel_applet_size_request(GtkWidget *widget, GtkRequisition *requisition) { MDockMatePanelApplet *self = MDOCK_MATE_PANEL_APPLET(widget); - if (self->dock) { - gtk_widget_size_request(GTK_WIDGET(self->dock), requisition); + gint nitems = mdock_widget_get_n_items(self->dock); + + gtk_widget_size_request(GTK_WIDGET(self->dock), requisition); + + g_debug("size request %dx%d", requisition->width, requisition->height); + + // Try to force a square aspect ratio for the icons + // by requesting a big enough major panel dimension + GtkAllocation allocation; + gtk_widget_get_allocation(GTK_WIDGET(self), &allocation); + gint spacing = gtk_box_get_spacing(GTK_BOX(self->dock)); + + if (mdock_mate_panel_applet_get_orientation(self) == GTK_ORIENTATION_HORIZONTAL) { + requisition->width = MAX(requisition->width, nitems * (allocation.height + spacing)); + requisition->height = MAX(requisition->height, allocation.height); + } else { + requisition->width = MAX(requisition->width, allocation.width); + requisition->height = MAX(requisition->height, nitems * (requisition->width + spacing)); } + + g_debug("size request %dx%d", requisition->width, requisition->height); } static void mdock_mate_panel_applet_class_init(MDockMatePanelAppletClass *klass) @@ -92,9 +119,20 @@ static void mdock_mate_panel_applet_class_init(MDockMatePanelAppletClass *klass) static void mdock_mate_panel_applet_init(MDockMatePanelApplet *self) { - self->dock = MDOCK_WIDGET(mdock_widget_new()); + MatePanelApplet *applet = MATE_PANEL_APPLET(self); + gchar *prefs_path = mate_panel_applet_get_preferences_path(applet); + + g_warn_if_fail(prefs_path); + + if (prefs_path) { + self->dock = MDOCK_WIDGET(mdock_widget_new_with_settings_path(prefs_path)); + } else { + self->dock = MDOCK_WIDGET(mdock_widget_new()); + } gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->dock)); + g_free(prefs_path); + g_object_bind_property_full(self, "orient", self->dock, "orientation", G_BINDING_DEFAULT, transform_applet_orient_to_orientation, @@ -104,12 +142,13 @@ static void mdock_mate_panel_applet_init(MDockMatePanelApplet *self) gtk_action_group_add_actions(action_group, menu_verbs, G_N_ELEMENTS(menu_verbs), self); - mate_panel_applet_set_flags(MATE_PANEL_APPLET(self), + mate_panel_applet_set_flags(applet, MATE_PANEL_APPLET_EXPAND_MINOR); - mate_panel_applet_setup_menu(MATE_PANEL_APPLET(self), + mate_panel_applet_setup_menu(applet, "" "", action_group); + mate_panel_applet_set_background_widget(applet, GTK_WIDGET(self)); g_object_unref(action_group); -- cgit v1.2.3