summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2015-01-23 01:11:07 +0100
committerJavier <dev.git@javispedro.com>2015-01-23 01:11:07 +0100
commitb711fa350a4aec9d9584e6b3623290201f7273a2 (patch)
treef58b38cfd6216dd01dc6be82017c694f34ee9382
parentca5aefe54c314f8dbbf3f09b55ebf9aa07ffbfd0 (diff)
downloadmdock-b711fa350a4aec9d9584e6b3623290201f7273a2.tar.gz
mdock-b711fa350a4aec9d9584e6b3623290201f7273a2.zip
loading gsettings
-rw-r--r--libmdock/Makefile.am2
-rw-r--r--libmdock/com.javispedro.mdock.widget.gschema.xml2
-rw-r--r--libmdock/mdock-item.c98
-rw-r--r--libmdock/mdock-item.h4
-rw-r--r--libmdock/mdock-widget.c89
5 files changed, 159 insertions, 36 deletions
diff --git a/libmdock/Makefile.am b/libmdock/Makefile.am
index 2d46925..cb8ca1d 100644
--- a/libmdock/Makefile.am
+++ b/libmdock/Makefile.am
@@ -1,5 +1,5 @@
lib_LTLIBRARIES = libmdock.la
-libmdock_la_SOURCES = mdock-widget.h mdock-widget.c mdock-enums.h mdock-enums.c mdock-item.h mdock-item.c matcher.h matcher.c app-id.h app-id.c thumbnailer.h thumbnailer.c
+libmdock_la_SOURCES = mdock-widget.h mdock-widget.c mdock-enums.h mdock-enums.c mdock-item.h mdock-item.c mdock-item-menu.c mdock-item-menu.h matcher.h matcher.c app-id.h app-id.c thumbnailer.h thumbnailer.c
libmdock_la_CPPFLAGS = $(GTK_CFLAGS) $(GIO_CFLAGS) $(WNCK_CFLAGS) $(GTOP_CFLAGS) -D_GNU_SOURCE -DG_LOG_DOMAIN=\"libmdock\"
libmdock_la_LIBADD = $(GTK_LIBS) $(GIO_LIBS) $(WNCK_LIBS) $(GTOP_LIBS)
diff --git a/libmdock/com.javispedro.mdock.widget.gschema.xml b/libmdock/com.javispedro.mdock.widget.gschema.xml
index c48dee4..103a94d 100644
--- a/libmdock/com.javispedro.mdock.widget.gschema.xml
+++ b/libmdock/com.javispedro.mdock.widget.gschema.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<schemalist>
<schema id="com.javispedro.mdock.widget">
- <key name="items" type="a(ss)">
+ <key name="items" type="as">
<default>[]</default>
<summary>Items in the dock</summary>
</key>
diff --git a/libmdock/mdock-item.c b/libmdock/mdock-item.c
index 2c9a836..9f87a6a 100644
--- a/libmdock/mdock-item.c
+++ b/libmdock/mdock-item.c
@@ -19,6 +19,7 @@
#include "mdock-enums.h"
#include "mdock-item.h"
+#include "mdock-item-menu.h"
#include "thumbnailer.h"
#define MDOCK_ITEM_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), MDOCK_TYPE_ITEM, MDockItemPrivate))
@@ -33,7 +34,9 @@ struct _MDockItemPrivate
WnckWindow *last_active;
- GtkMenu *menu;
+ MDockItemMenu *menu;
+
+ GtkMenu *right_menu;
GtkImageMenuItem *menu_close_all;
GtkImageMenuItem *menu_pin;
GtkImageMenuItem *menu_launch;
@@ -43,6 +46,7 @@ G_DEFINE_TYPE (MDockItem, mdock_item, GTK_TYPE_WIDGET)
enum {
PROP_0,
+ PROP_PINNED,
PROP_DESKTOP_APP_INFO,
PROP_ICON_SIZE,
N_PROPERTIES
@@ -97,7 +101,7 @@ static void mdock_item_update_icon(MDockItem *self)
static void mdock_item_update_tooltip(MDockItem *self)
{
- gtk_widget_set_tooltip_text(GTK_WIDGET(self), mdock_item_get_display_name(self));
+ // TODO gtk_widget_set_tooltip_text(GTK_WIDGET(self), mdock_item_get_display_name(self));
}
static void mdock_item_update_menu(MDockItem *self)
@@ -196,28 +200,7 @@ static gboolean mdock_item_button_press(GtkWidget *widget, GdkEventButton *event
}
} else if (self->priv->appinfo) {
// No windows, but we have an application to launch!
- GError *error = NULL;
- if (!g_app_info_launch(G_APP_INFO(self->priv->appinfo), NULL, NULL, &error)) {
- GtkWidget *msg;
-
- g_warning("Cannot launch '%s': %s",
- g_app_info_get_display_name(G_APP_INFO(self->priv->appinfo)),
- error->message);
-
- msg = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_OK,
- "Cannot launch '%s': %s",
- g_app_info_get_display_name(G_APP_INFO(self->priv->appinfo)),
- error->message);
-
- g_signal_connect_swapped(msg, "response",
- G_CALLBACK(gtk_widget_destroy), msg);
-
- gtk_widget_show_all(msg);
- g_error_free(error);
- }
+ mdock_item_launch(self);
} else {
g_warning("A MDockItem has no windows and no appinfo to launch");
}
@@ -225,7 +208,7 @@ static gboolean mdock_item_button_press(GtkWidget *widget, GdkEventButton *event
break;
case 3:
- gtk_menu_popup(self->priv->menu,
+ gtk_menu_popup(self->priv->right_menu,
NULL, NULL, NULL, NULL,
event->button, event->time);
break;
@@ -256,10 +239,14 @@ static void mdock_item_set_property(GObject *object,
{
MDockItem *self = MDOCK_ITEM(object);
switch (property_id) {
+ case PROP_PINNED:
+ self->priv->pinned = g_value_get_boolean(value);
+ break;
case PROP_DESKTOP_APP_INFO:
self->priv->appinfo = g_value_dup_object(value);
mdock_item_update_icon(self);
mdock_item_update_tooltip(self);
+ mdock_item_update_menu(self);
break;
case PROP_ICON_SIZE:
self->priv->icon_size = g_value_get_uint(value);
@@ -279,6 +266,9 @@ static void mdock_item_get_property(GObject *object,
{
MDockItem *self = MDOCK_ITEM(object);
switch (property_id) {
+ case PROP_PINNED:
+ g_value_set_boolean(value, self->priv->pinned);
+ break;
case PROP_DESKTOP_APP_INFO:
g_value_set_object(value, self->priv->appinfo);
break;
@@ -297,6 +287,7 @@ static void mdock_item_dispose(GObject *object)
g_clear_object(&self->priv->appinfo);
g_clear_object(&self->priv->icon);
g_clear_object(&self->priv->menu);
+ g_clear_object(&self->priv->right_menu);
g_clear_object(&self->priv->menu_close_all);
g_clear_object(&self->priv->menu_pin);
g_clear_object(&self->priv->menu_launch);
@@ -318,21 +309,26 @@ static void mdock_item_init(MDockItem *self)
gtk_widget_add_events(GTK_WIDGET(self), GDK_BUTTON_PRESS_MASK);
- self->priv->menu = g_object_ref_sink(gtk_menu_new());
+ self->priv->menu = g_object_ref_sink(mdock_item_menu_new());
+ gtk_widget_set_tooltip_window(GTK_WIDGET(self), GTK_WINDOW(self->priv->menu));
+
+ self->priv->right_menu = g_object_ref_sink(gtk_menu_new());
self->priv->menu_close_all = g_object_ref_sink(gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, NULL));
- gtk_menu_shell_append(GTK_MENU_SHELL(self->priv->menu),
+ gtk_menu_shell_append(GTK_MENU_SHELL(self->priv->right_menu),
GTK_WIDGET(self->priv->menu_close_all));
g_signal_connect_swapped(self->priv->menu_close_all, "activate",
G_CALLBACK(mdock_item_close_all_windows), self);
self->priv->menu_pin = g_object_ref_sink(gtk_image_menu_item_new_with_mnemonic("_Pin"));
- gtk_menu_shell_append(GTK_MENU_SHELL(self->priv->menu),
+ gtk_menu_shell_append(GTK_MENU_SHELL(self->priv->right_menu),
GTK_WIDGET(self->priv->menu_pin));
self->priv->menu_launch = g_object_ref_sink(gtk_image_menu_item_new_with_mnemonic("_New instance"));
- gtk_menu_shell_append(GTK_MENU_SHELL(self->priv->menu),
+ gtk_menu_shell_append(GTK_MENU_SHELL(self->priv->right_menu),
GTK_WIDGET(self->priv->menu_launch));
+ g_signal_connect_swapped(self->priv->menu_launch, "activate",
+ G_CALLBACK(mdock_item_launch), self);
}
static void
@@ -351,6 +347,12 @@ mdock_item_class_init(MDockItemClass *klass)
widget_class->button_press_event = mdock_item_button_press;
widget_class->expose_event = mdock_item_expose;
+ obj_properties[PROP_PINNED] = g_param_spec_boolean("pinned",
+ "Pinned launcher",
+ "Set whether this launcher is pinned",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
obj_properties[PROP_DESKTOP_APP_INFO] = g_param_spec_object("desktop-app-info",
"The GDesktopAppInfo this application or launcher refers to",
"Set the GDesktopAppInfo this application or launcher refers to",
@@ -374,6 +376,16 @@ MDockItem *mdock_item_new()
return g_object_new(MDOCK_TYPE_ITEM, NULL);
}
+gboolean mdock_item_get_pinned(MDockItem *self)
+{
+ return self->priv->pinned;
+}
+
+void mdock_item_set_pinned(MDockItem *self, gboolean pinned)
+{
+ g_object_set(self, "pinned", pinned, NULL);
+}
+
GDesktopAppInfo *mdock_item_get_desktop_app_info(MDockItem *self)
{
return g_object_ref(self->priv->appinfo);
@@ -384,6 +396,34 @@ void mdock_item_set_desktop_app_info(MDockItem *self, GDesktopAppInfo *app_info)
g_object_set(self, "desktop-app-info", app_info, NULL);
}
+void mdock_item_launch(MDockItem *self)
+{
+ g_return_if_fail(self->priv->appinfo);
+ GError *error = NULL;
+ g_debug("Launching '%s'", g_app_info_get_commandline(G_APP_INFO(self->priv->appinfo)));
+ if (!g_app_info_launch(G_APP_INFO(self->priv->appinfo), NULL, NULL, &error)) {
+ GtkWidget *msg;
+
+ g_warning("Cannot launch '%s': %s",
+ g_app_info_get_display_name(G_APP_INFO(self->priv->appinfo)),
+ error->message);
+
+ msg = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(self))),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK,
+ "Cannot launch '%s': %s",
+ g_app_info_get_display_name(G_APP_INFO(self->priv->appinfo)),
+ error->message);
+
+ g_signal_connect_swapped(msg, "response",
+ G_CALLBACK(gtk_widget_destroy), msg);
+
+ gtk_widget_show_all(msg);
+ g_error_free(error);
+ }
+}
+
void mdock_item_add_window(MDockItem *self, WnckWindow *window)
{
thumbnailer_enable_for_window(window);
diff --git a/libmdock/mdock-item.h b/libmdock/mdock-item.h
index 9876ce8..f9fe657 100644
--- a/libmdock/mdock-item.h
+++ b/libmdock/mdock-item.h
@@ -52,8 +52,12 @@ struct _MDockItemClass {
GType mdock_item_get_type(void) G_GNUC_CONST;
MDockItem *mdock_item_new();
+gboolean mdock_item_get_pinned(MDockItem *self);
+void mdock_item_set_pinned(MDockItem *self, gboolean pinned);
+
GDesktopAppInfo *mdock_item_get_desktop_app_info(MDockItem *self);
void mdock_item_set_desktop_app_info(MDockItem *self, GDesktopAppInfo *app_info);
+void mdock_item_launch(MDockItem *self);
void mdock_item_add_window(MDockItem *self, WnckWindow *window);
void mdock_item_remove_window(MDockItem *self, WnckWindow *window);
diff --git a/libmdock/mdock-widget.c b/libmdock/mdock-widget.c
index 27f8f50..06080bf 100644
--- a/libmdock/mdock-widget.c
+++ b/libmdock/mdock-widget.c
@@ -76,8 +76,8 @@ static void handle_window_closed(MDockWidget *self, WnckWindow *window, WnckScre
mdock_item_remove_window(item, window);
g_hash_table_remove(self->priv->window_to_item, window);
- if (mdock_item_get_num_windows(item) == 0) {
- // Removing window!
+ if (mdock_item_get_num_windows(item) == 0 && !mdock_item_get_pinned(item)) {
+ // Removing item from dock
g_hash_table_foreach_remove(self->priv->appid_to_item, filter_deleted_group, iter);
g_hash_table_foreach_remove(self->priv->desktopid_to_item, filter_deleted_group, iter);
g_sequence_remove(iter);
@@ -137,6 +137,81 @@ static void handle_window_opened(MDockWidget *self, WnckWindow *window, WnckScre
gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(item), TRUE, FALSE, 0);
}
+static void load_items_from_settings(MDockWidget *self, GSettings *settings)
+{
+ GVariantIter *set_iter;
+ GVariant *set_value;
+ GSequenceIter *seq_iter = g_sequence_get_begin_iter(self->priv->items);
+
+ g_settings_get(settings, "items", "as", &set_iter);
+ set_value = g_variant_iter_next_value(set_iter);
+
+ g_debug("Loading settings %p %p", set_value, seq_iter);
+
+ while (set_value || !g_sequence_iter_is_end(seq_iter)) {
+ gboolean advance_set = FALSE, advance_seq = FALSE;
+ MDockItem *item = NULL;
+ GDesktopAppInfo *seq_appinfo = NULL;
+ GDesktopAppInfo *set_appinfo = NULL;
+
+ g_debug("Iteration %p %p", set_value, seq_iter);
+
+ if (!g_sequence_iter_is_end(seq_iter)) {
+ item = MDOCK_ITEM(g_sequence_get(seq_iter));
+ seq_appinfo = mdock_item_get_desktop_app_info(item);
+ }
+ if (set_value) {
+ set_appinfo = g_desktop_app_info_new_from_filename(g_variant_get_string(set_value, NULL));
+ }
+
+ if (set_appinfo && seq_appinfo) {
+ const gchar *set_desktopid = g_app_info_get_id(G_APP_INFO(set_appinfo));
+ const gchar *seq_desktopid = g_app_info_get_id(G_APP_INFO(seq_appinfo));
+ const gboolean seq_pinned = mdock_item_get_pinned(item);
+
+ // TODO broken
+ g_warning("broken");
+ } else if (set_appinfo) {
+ g_debug("from set only");
+ item = mdock_item_new();
+ mdock_item_set_desktop_app_info(item, set_appinfo);
+ mdock_item_set_pinned(item, TRUE);
+
+ GSequenceIter *iter = g_sequence_append(self->priv->items, item);
+ const gchar *desktopid = g_app_info_get_id(G_APP_INFO(set_appinfo));
+ g_hash_table_insert(self->priv->desktopid_to_item, g_strdup(desktopid), iter);
+ gtk_widget_show(GTK_WIDGET(item));
+ gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(item), TRUE, FALSE, 0);
+
+ advance_set = TRUE;
+ } else if (seq_appinfo) {
+ g_debug("from seq only");
+ if (mdock_item_get_pinned(item)) {
+ mdock_item_set_pinned(item, FALSE);
+ }
+ advance_seq = TRUE;
+ }
+
+ g_object_unref(set_appinfo);
+
+ if (advance_set && set_appinfo) {
+ g_variant_unref(set_value);
+ set_value = g_variant_iter_next_value(set_iter);
+
+ }
+ if (advance_seq && !g_sequence_iter_is_end(seq_iter)) {
+ seq_iter = g_sequence_iter_next(seq_iter);
+ }
+ }
+
+ g_variant_iter_free(set_iter);
+}
+
+static void handle_settings_items_changed(MDockWidget *self, gchar *key, GSettings *settings)
+{
+ load_items_from_settings(self, settings);
+}
+
static void mdock_widget_constructed(GObject *obj)
{
MDockWidget *self = MDOCK_WIDGET(obj);
@@ -144,14 +219,16 @@ static void mdock_widget_constructed(GObject *obj)
g_debug("Constructing with path: %s", self->priv->settings_path);
self->priv->settings = g_settings_new_with_path("com.javispedro.mdock.widget",
self->priv->settings_path);
+ g_signal_connect_object(self->priv->settings, "changed::items",
+ G_CALLBACK(handle_settings_items_changed), self, G_CONNECT_SWAPPED);
self->priv->wnck_screen = wnck_screen_get_default();
g_signal_connect_object(self->priv->wnck_screen, "active-window-changed",
- G_CALLBACK(handle_active_window_changed), self, G_CONNECT_SWAPPED);
+ G_CALLBACK(handle_active_window_changed), self, G_CONNECT_SWAPPED);
g_signal_connect_object(self->priv->wnck_screen, "window-closed",
- G_CALLBACK(handle_window_closed), self, G_CONNECT_SWAPPED);
+ G_CALLBACK(handle_window_closed), self, G_CONNECT_SWAPPED);
g_signal_connect_object(self->priv->wnck_screen, "window-opened",
- G_CALLBACK(handle_window_opened), self, G_CONNECT_SWAPPED);
+ G_CALLBACK(handle_window_opened), self, G_CONNECT_SWAPPED);
self->priv->items = g_sequence_new(NULL);
self->priv->appid_to_item = g_hash_table_new_full(app_id_hash, app_id_equal,
@@ -161,6 +238,8 @@ static void mdock_widget_constructed(GObject *obj)
self->priv->window_to_item = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, NULL);
+ load_items_from_settings(self, self->priv->settings);
+
GList *windows = wnck_screen_get_windows_stacked(self->priv->wnck_screen);
for (GList *l = windows; l; l = g_list_next(l)) {
WnckWindow *window = l->data;