From 8a483a611dcdf1aeb97b9b383affc4c239adebd1 Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Sat, 11 Feb 2012 12:50:09 +0300 Subject: [PATCH] Single click option to open items on desktop This patch adds support to launch items from a single click based on an xfconf property /desktop-icons/single-click. Also adds a checkbox to xfdesktop-settings. Bug 1797. Code for changing the cursor to a "hand" when hovering over items was provided by Lionel Le Folgoc --- doc/README.xfconf | 1 + settings/main.c | 10 ++- settings/xfdesktop-settings-ui.glade | 10 +++ src/xfdesktop-icon-view.c | 134 ++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 1 deletions(-) diff --git a/doc/README.xfconf b/doc/README.xfconf index 2fa1c40..bcc68e4 100644 --- a/doc/README.xfconf +++ b/doc/README.xfconf @@ -37,6 +37,7 @@ property is listd after the name. + diff --git a/settings/main.c b/settings/main.c index 1f76be9..68fe336 100644 --- a/settings/main.c +++ b/settings/main.c @@ -69,6 +69,7 @@ #define DESKTOP_ICONS_STYLE_PROP "/desktop-icons/style" #define DESKTOP_ICONS_ICON_SIZE_PROP "/desktop-icons/icon-size" #define DESKTOP_ICONS_FONT_SIZE_PROP "/desktop-icons/font-size" +#define DESKTOP_ICONS_SINGLE_CLICK_PROP "/desktop-icons/single-click" #define DESKTOP_ICONS_CUSTOM_FONT_SIZE_PROP "/desktop-icons/use-custom-font-size" #define DESKTOP_ICONS_SHOW_HOME "/desktop-icons/file-icons/show-home" #define DESKTOP_ICONS_SHOW_TRASH "/desktop-icons/file-icons/show-trash" @@ -1225,7 +1226,8 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml, { gint i, j, nmonitors, nscreens; GtkWidget *appearance_container, *chk_custom_font_size, - *spin_font_size, *color_style_widget, *w, *box; + *spin_font_size, *color_style_widget, *w, *box, + *chk_single_click; appearance_container = GTK_WIDGET(gtk_builder_get_object(main_gxml, "notebook_screens")); @@ -1234,6 +1236,9 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml, "chk_custom_font_size")); spin_font_size = GTK_WIDGET(gtk_builder_get_object(main_gxml, "spin_font_size")); + chk_single_click = GTK_WIDGET(gtk_builder_get_object(main_gxml, + "chk_single_click")); + g_signal_connect(G_OBJECT(chk_custom_font_size), "toggled", G_CALLBACK(cb_xfdesktop_chk_custom_font_size_toggled), spin_font_size); @@ -1487,6 +1492,9 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml, xfconf_g_property_bind(channel, DESKTOP_ICONS_CUSTOM_FONT_SIZE_PROP, G_TYPE_BOOLEAN, G_OBJECT(chk_custom_font_size), "active"); + xfconf_g_property_bind(channel, DESKTOP_ICONS_SINGLE_CLICK_PROP, + G_TYPE_BOOLEAN, G_OBJECT(chk_single_click), + "active"); setup_special_icon_list(main_gxml, channel); } diff --git a/settings/xfdesktop-settings-ui.glade b/settings/xfdesktop-settings-ui.glade index 0ae289c..766a73a 100644 --- a/settings/xfdesktop-settings-ui.glade +++ b/settings/xfdesktop-settings-ui.glade @@ -685,6 +685,16 @@ + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Single _click to activate items + True + True + + + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c index 0736006..f046437 100644 --- a/src/xfdesktop-icon-view.c +++ b/src/xfdesktop-icon-view.c @@ -48,9 +48,11 @@ #include "xfdesktop-icon-view.h" #include "xfdesktop-marshal.h" +#include "xfdesktop-common.h" #include #include +#include #define DEFAULT_FONT_SIZE 12 #define DEFAULT_ICON_SIZE 32 @@ -135,6 +137,8 @@ struct _XfdesktopIconViewPrivate gint press_start_y; GdkRectangle band_rect; + XfconfChannel *channel; + GdkColor *selection_box_color; guchar selection_box_alpha; @@ -168,8 +172,18 @@ struct _XfdesktopIconViewPrivate gdouble cell_text_width_proportion; gboolean ellipsize_icon_labels; + gboolean single_click; }; +static void xfce_icon_view_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void xfce_icon_view_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + static gboolean xfdesktop_icon_view_button_press(GtkWidget *widget, GdkEventButton *evt, gpointer user_data); @@ -337,6 +351,13 @@ enum TARGET_XFDESKTOP_ICON = 9999, }; +enum +{ + PROP_0 = 0, + PROP_SINGLE_CLICK, +}; + + static const GtkTargetEntry icon_view_targets[] = { { "XFDESKTOP_ICON", GTK_TARGET_SAME_APP, TARGET_XFDESKTOP_ICON } }; @@ -362,6 +383,8 @@ xfdesktop_icon_view_class_init(XfdesktopIconViewClass *klass) g_type_class_add_private(klass, sizeof(XfdesktopIconViewPrivate)); gobject_class->finalize = xfdesktop_icon_view_finalize; + gobject_class->set_property = xfce_icon_view_set_property; + gobject_class->get_property = xfce_icon_view_get_property; widget_class->style_set = xfdesktop_icon_view_style_set; widget_class->realize = xfdesktop_icon_view_realize; @@ -545,6 +568,21 @@ xfdesktop_icon_view_class_init(XfdesktopIconViewClass *klass) 0.0, 50.0, 4.0, G_PARAM_READABLE)); +#define XFDESKTOP_PARAM_FLAGS (G_PARAM_READWRITE \ + | G_PARAM_CONSTRUCT \ + | G_PARAM_STATIC_NAME \ + | G_PARAM_STATIC_NICK \ + | G_PARAM_STATIC_BLURB) + + g_object_class_install_property(gobject_class, PROP_SINGLE_CLICK, + g_param_spec_boolean("single-click", + "single-click", + "single-click", + FALSE, + XFDESKTOP_PARAM_FLAGS)); + +#undef XFDESKTOP_PARAM_FLAGS + /* same binding entries as GtkIconView */ gtk_binding_entry_add_signal(binding_set, GDK_a, GDK_CONTROL_MASK, "select-all", 0); @@ -633,6 +671,14 @@ xfdesktop_icon_view_init(XfdesktopIconView *icon_view) g_object_set(G_OBJECT(icon_view), "has-tooltip", TRUE, NULL); g_signal_connect(G_OBJECT(icon_view), "query-tooltip", G_CALLBACK(xfdesktop_icon_view_show_tooltip), NULL); + + icon_view->priv->channel = xfconf_channel_new (XFDESKTOP_CHANNEL); + + xfconf_g_property_bind(icon_view->priv->channel, + "/desktop-icons/single-click", + G_TYPE_BOOLEAN, + G_OBJECT(icon_view), + "single_click"); GTK_WIDGET_SET_FLAGS(GTK_WIDGET(icon_view), GTK_NO_WINDOW); } @@ -654,11 +700,54 @@ xfdesktop_icon_view_finalize(GObject *obj) g_list_foreach(icon_view->priv->pending_icons, (GFunc)g_object_unref, NULL); g_list_free(icon_view->priv->pending_icons); /* icon_view->priv->icons should be cleared in _unrealize() */ + + if (icon_view->priv->channel) { + g_object_unref (icon_view->priv->channel); + icon_view->priv->channel = NULL; + } G_OBJECT_CLASS(xfdesktop_icon_view_parent_class)->finalize(obj); } static void +xfce_icon_view_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(object); + + switch(property_id) { + case PROP_SINGLE_CLICK: + icon_view->priv->single_click = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +xfce_icon_view_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(object); + + switch(property_id) { + case PROP_SINGLE_CLICK: + g_value_set_boolean(value, icon_view->priv->single_click); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void xfdesktop_icon_view_add_move_binding(GtkBindingSet *binding_set, guint keyval, guint modmask, @@ -802,6 +891,14 @@ xfdesktop_icon_view_button_press(GtkWidget *widget, } static gboolean +xfdesktop_icon_view_get_single_click(XfdesktopIconView *icon_view) +{ + g_return_val_if_fail(XFDESKTOP_IS_ICON_VIEW(icon_view), FALSE); + + return icon_view->priv->single_click; +} + +static gboolean xfdesktop_icon_view_button_release(GtkWidget *widget, GdkEventButton *evt, gpointer user_data) @@ -810,6 +907,23 @@ xfdesktop_icon_view_button_release(GtkWidget *widget, TRACE("entering btn=%d", evt->button); + /* single-click */ + if(xfdesktop_icon_view_get_single_click(icon_view) + && evt->button == 1 + && !(evt->state & GDK_SHIFT_MASK) + && !icon_view->priv->definitely_dragging + && !icon_view->priv->definitely_rubber_banding) { + XfdesktopIcon *icon; + GList *icon_l = g_list_find_custom(icon_view->priv->icons, evt, + (GCompareFunc)xfdesktop_check_icon_clicked); + if(icon_l && (icon = icon_l->data)) { + icon_view->priv->cursor = icon; + g_signal_emit(G_OBJECT(icon_view), __signals[SIG_ICON_ACTIVATED], + 0, NULL); + xfdesktop_icon_activated(icon); + } + } + if(evt->button == 1) { DBG("unsetting stuff"); icon_view->priv->definitely_dragging = FALSE; @@ -874,6 +988,12 @@ xfdesktop_icon_view_focus_out(GtkWidget *widget, xfdesktop_icon_view_invalidate_icon(icon_view, l->data, FALSE); } + if(G_UNLIKELY(icon_view->priv->single_click)) { + if(G_LIKELY(icon_view->priv->parent_window->window != NULL)) { + gdk_window_set_cursor(icon_view->priv->parent_window->window, NULL); + } + } + return FALSE; } @@ -1049,6 +1169,11 @@ xfdesktop_icon_view_motion_notify(GtkWidget *widget, /* normal movement; highlight icons as they go under the pointer */ if(icon_view->priv->item_under_pointer) { + if(G_UNLIKELY(icon_view->priv->single_click)) { + GdkCursor *cursor = gdk_cursor_new(GDK_HAND2); + gdk_window_set_cursor(evt->window, cursor); + gdk_cursor_unref(cursor); + } if(!xfdesktop_icon_get_extents(icon_view->priv->item_under_pointer, NULL, NULL, &extents) || !xfdesktop_rectangle_contains_point(&extents, evt->x, evt->y)) @@ -1060,6 +1185,9 @@ xfdesktop_icon_view_motion_notify(GtkWidget *widget, #endif } } else { + if(G_UNLIKELY(icon_view->priv->single_click)) { + gdk_window_set_cursor(evt->window, NULL); + } icon = xfdesktop_icon_view_widget_coords_to_item(icon_view, evt->x, evt->y); @@ -1093,6 +1221,12 @@ xfdesktop_icon_view_leave_notify(GtkWidget *widget, xfdesktop_icon_view_invalidate_icon(icon_view, icon, FALSE); #endif } + + if(G_UNLIKELY(icon_view->priv->single_click)) { + if(GTK_WIDGET_REALIZED(widget)) { + gdk_window_set_cursor(widget->window, NULL); + } + } return FALSE; } -- 1.7.5.4