/* * Copyright 2015 Javier S. Pedro * * This file is part of MDock. * * MDock 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 3 of the License, or * (at your option) any later version. * * MDock 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 Lesser General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MDock. If not, see . */ #include #include "mdock-item-menu.h" #define MDOCK_ITEM_MENU_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), MDOCK_TYPE_ITEM_MENU, MDockItemMenuPrivate)) struct _MDockItemMenuPrivate { GtkSeparatorMenuItem *menu_sep1; GtkImageMenuItem *menu_close_all; GtkImageMenuItem *menu_pin; GtkImageMenuItem *menu_launch; }; G_DEFINE_TYPE (MDockItemMenu, mdock_item_menu, GTK_TYPE_MENU) enum { PROP_0, PROP_ITEM, N_PROPERTIES }; static GParamSpec *obj_properties[N_PROPERTIES] = { NULL }; static void handle_item_pinned(MDockItemMenu *self, GParamSpec *spec, MDockItem *item) { const gboolean pinned = mdock_item_get_pinned(item); gtk_menu_item_set_label(GTK_MENU_ITEM(self->priv->menu_pin), pinned ? _("Un_pin") : _("_Pin")); } static void handle_item_desktop_app_info(MDockItemMenu *self, GParamSpec *spec, MDockItem *item) { GDesktopAppInfo *appinfo = mdock_item_get_desktop_app_info(item); gtk_widget_set_visible(GTK_WIDGET(self->priv->menu_pin), appinfo != NULL); gtk_widget_set_visible(GTK_WIDGET(self->priv->menu_launch), appinfo != NULL); if (!gtk_image_menu_item_get_image(self->priv->menu_launch) && appinfo) { gint width, height; if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height)) { GtkIconTheme *theme = gtk_icon_theme_get_default(); gint icon_size = MAX(width, height); GIcon *icon = g_app_info_get_icon(G_APP_INFO(appinfo)); GtkIconInfo *info = gtk_icon_theme_lookup_by_gicon(theme, icon, icon_size, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_FORCE_SIZE); if (info) { GdkPixbuf *pixbuf = gtk_icon_info_load_icon(info, NULL); if (pixbuf) { GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); gtk_image_menu_item_set_image(self->priv->menu_launch, image); g_object_unref(pixbuf); } gtk_icon_info_free(info); } } } } static void handle_item_n_windows(MDockItemMenu *self, GParamSpec *spec, MDockItem *item) { gtk_widget_set_visible(GTK_WIDGET(self->priv->menu_close_all), mdock_item_has_windows(item)); } static void mdock_item_menu_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { MDockItemMenu *self = MDOCK_ITEM_MENU(object); switch (property_id) { case PROP_ITEM: g_clear_object(&self->item); self->item = g_value_dup_object(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } } static void mdock_item_menu_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { MDockItemMenu *self = MDOCK_ITEM_MENU(object); switch (property_id) { case PROP_ITEM: g_value_set_object(value, self->item); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } } static void mdock_item_menu_constructed(GObject *object) { MDockItemMenu *self = MDOCK_ITEM_MENU(object); g_signal_connect_object(self->priv->menu_close_all, "activate", G_CALLBACK(mdock_item_close_all_windows), self->item, G_CONNECT_SWAPPED); g_signal_connect_object(self->priv->menu_pin, "activate", G_CALLBACK(mdock_item_toggle_pinned), self->item, G_CONNECT_SWAPPED); g_signal_connect_object(self->priv->menu_launch, "activate", G_CALLBACK(mdock_item_launch), self->item, G_CONNECT_SWAPPED); g_signal_connect_object(self->item, "notify::pinned", G_CALLBACK(handle_item_pinned), self, G_CONNECT_SWAPPED); g_signal_connect_object(self->item, "notify::desktop-app-info", G_CALLBACK(handle_item_desktop_app_info), self, G_CONNECT_SWAPPED); g_signal_connect_object(self->item, "notify::n-windows", G_CALLBACK(handle_item_n_windows), self, G_CONNECT_SWAPPED); handle_item_desktop_app_info(self, NULL, self->item); handle_item_pinned(self, NULL, self->item); } static void mdock_item_menu_dispose(GObject *object) { MDockItemMenu *self = MDOCK_ITEM_MENU(object); g_clear_object(&self->item); G_OBJECT_CLASS (mdock_item_menu_parent_class)->dispose(object); } static void mdock_item_menu_finalize (GObject *object) { G_OBJECT_CLASS (mdock_item_menu_parent_class)->finalize (object); } static void mdock_item_menu_init (MDockItemMenu *self) { self->priv = MDOCK_ITEM_MENU_GET_PRIVATE (self); self->priv->menu_sep1 = GTK_SEPARATOR_MENU_ITEM(gtk_separator_menu_item_new()); gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_sep1)); self->priv->menu_close_all = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, NULL)); gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_close_all)); self->priv->menu_pin = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new_with_mnemonic(_("_Pin"))); gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_pin)); self->priv->menu_launch = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new_with_mnemonic(_("_New instance"))); gtk_menu_shell_append(GTK_MENU_SHELL(self), GTK_WIDGET(self->priv->menu_launch)); } static void mdock_item_menu_class_init (MDockItemMenuClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); obj_class->set_property = mdock_item_menu_set_property; obj_class->get_property = mdock_item_menu_get_property; obj_class->constructed = mdock_item_menu_constructed; obj_class->dispose = mdock_item_menu_dispose; obj_class->finalize = mdock_item_menu_finalize; g_type_class_add_private(obj_class, sizeof(MDockItemMenuPrivate)); obj_properties[PROP_ITEM] = g_param_spec_object("item", "The MDockItem the options in this menu apply to", "Set the MDockItem the options in this menu apply to", MDOCK_TYPE_ITEM, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(obj_class, N_PROPERTIES, obj_properties); } MDockItemMenu * mdock_item_menu_new(MDockItem *item) { return g_object_new(MDOCK_TYPE_ITEM_MENU, "item", item, NULL); }