1
From bab7bc4b9af228f5e1b313ebd83f1cfd655dde10 Mon Sep 17 00:00:00 2001
2
From: Eric Koegel <eric.koegel@gmail.com>
3
Date: Sat, 11 Feb 2012 12:50:09 +0300
4
Subject: Single click option to open items on desktop
6
This patch adds support to launch items from a single click based
7
on an xfconf property /desktop-icons/single-click. Also adds a
8
checkbox to xfdesktop-settings. Bug 1797.
9
Code for changing the cursor to a "hand" when hovering over items
10
was provided by Lionel Le Folgoc <lionel@lefolgoc.net>
12
Slightly modified for Xubuntu to apply cleanly. The added string has
13
been modified to match the option name in Thunar, so we can reuse
14
existing translations.
17
doc/README.xfconf | 1 +
18
settings/main.c | 9 ++-
19
settings/xfdesktop-settings-ui.glade | 10 +++
20
src/xfdesktop-icon-view.c | 136 ++++++++++++++++++++++++++++++++++
21
4 files changed, 155 insertions(+), 1 deletions(-)
23
diff --git a/settings/main.c b/settings/main.c
24
index 62bcbff..554f802 100644
28
#define DESKTOP_ICONS_ICON_SIZE_PROP "/desktop-icons/icon-size"
29
#define DESKTOP_ICONS_FONT_SIZE_PROP "/desktop-icons/font-size"
30
#define DESKTOP_ICONS_CUSTOM_FONT_SIZE_PROP "/desktop-icons/use-custom-font-size"
31
+#define DESKTOP_ICONS_SINGLE_CLICK_PROP "/desktop-icons/single-click"
32
#define DESKTOP_ICONS_SHOW_THUMBNAILS_PROP "/desktop-icons/show-thumbnails"
33
#define DESKTOP_ICONS_SHOW_HOME "/desktop-icons/file-icons/show-home"
34
#define DESKTOP_ICONS_SHOW_TRASH "/desktop-icons/file-icons/show-trash"
35
@@ -1263,7 +1264,7 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml,
36
gint i, j, nmonitors, nscreens;
37
GtkWidget *dialog, *appearance_container, *chk_custom_font_size,
38
*spin_font_size, *color_style_widget, *w, *box,
39
- *spin_icon_size, *chk_show_thumbnails;
40
+ *spin_icon_size, *chk_show_thumbnails, *chk_single_click;
42
dialog = GTK_WIDGET(gtk_builder_get_object(main_gxml, "prefs_dialog"));
43
appearance_container = GTK_WIDGET(gtk_builder_get_object(main_gxml,
44
@@ -1284,6 +1285,9 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml,
45
"chk_custom_font_size"));
46
spin_font_size = GTK_WIDGET(gtk_builder_get_object(main_gxml, "spin_font_size"));
48
+ chk_single_click = GTK_WIDGET(gtk_builder_get_object(main_gxml,
49
+ "chk_single_click"));
51
g_signal_connect(G_OBJECT(chk_custom_font_size), "toggled",
52
G_CALLBACK(cb_xfdesktop_chk_custom_font_size_toggled),
54
@@ -1538,6 +1542,9 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml,
55
xfconf_g_property_bind(channel, DESKTOP_ICONS_SHOW_THUMBNAILS_PROP,
56
G_TYPE_BOOLEAN, G_OBJECT(chk_show_thumbnails),
58
+ xfconf_g_property_bind(channel, DESKTOP_ICONS_SINGLE_CLICK_PROP,
59
+ G_TYPE_BOOLEAN, G_OBJECT(chk_single_click),
62
setup_special_icon_list(main_gxml, channel);
64
diff --git a/settings/xfdesktop-settings-ui.glade b/settings/xfdesktop-settings-ui.glade
65
index 5fcc836..eef177e 100644
66
--- a/settings/xfdesktop-settings-ui.glade
67
+++ b/settings/xfdesktop-settings-ui.glade
72
+ <object class="GtkCheckButton" id="chk_single_click">
73
+ <property name="visible">True</property>
74
+ <property name="can_focus">True</property>
75
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
76
+ <property name="label" translatable="yes">_Single click to activate items</property>
77
+ <property name="use_underline">True</property>
78
+ <property name="draw_indicator">True</property>
82
<object class="GtkHBox" id="hbox9">
83
<property name="visible">True</property>
84
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
85
diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c
86
index d21b160..d7dfdc4 100644
87
--- a/src/xfdesktop-icon-view.c
88
+++ b/src/xfdesktop-icon-view.c
90
#include "xfdesktop-icon-view.h"
91
#include "xfdesktop-file-icon-manager.h"
92
#include "xfdesktop-marshal.h"
93
+#include "xfdesktop-common.h"
94
#include "xfce-desktop.h"
96
#include <libwnck/libwnck.h>
97
#include <libxfce4ui/libxfce4ui.h>
98
+#include <xfconf/xfconf.h>
100
#define DEFAULT_FONT_SIZE 12
101
#define DEFAULT_ICON_SIZE 32
102
@@ -137,6 +139,8 @@ struct _XfdesktopIconViewPrivate
104
GdkRectangle band_rect;
106
+ XfconfChannel *channel;
108
GdkColor *selection_box_color;
109
guchar selection_box_alpha;
111
@@ -171,8 +175,19 @@ struct _XfdesktopIconViewPrivate
113
gboolean ellipsize_icon_labels;
116
+ gboolean single_click;
119
+static void xfce_icon_view_set_property(GObject *object,
121
+ const GValue *value,
122
+ GParamSpec *pspec);
123
+static void xfce_icon_view_get_property(GObject *object,
126
+ GParamSpec *pspec);
128
static gboolean xfdesktop_icon_view_button_press(GtkWidget *widget,
131
@@ -340,6 +355,13 @@ enum
132
TARGET_XFDESKTOP_ICON = 9999,
142
static const GtkTargetEntry icon_view_targets[] = {
143
{ "XFDESKTOP_ICON", GTK_TARGET_SAME_APP, TARGET_XFDESKTOP_ICON }
145
@@ -365,6 +387,8 @@ xfdesktop_icon_view_class_init(XfdesktopIconViewClass *klass)
146
g_type_class_add_private(klass, sizeof(XfdesktopIconViewPrivate));
148
gobject_class->finalize = xfdesktop_icon_view_finalize;
149
+ gobject_class->set_property = xfce_icon_view_set_property;
150
+ gobject_class->get_property = xfce_icon_view_get_property;
152
widget_class->style_set = xfdesktop_icon_view_style_set;
153
widget_class->realize = xfdesktop_icon_view_realize;
154
@@ -555,6 +579,21 @@ xfdesktop_icon_view_class_init(XfdesktopIconViewClass *klass)
158
+#define XFDESKTOP_PARAM_FLAGS (G_PARAM_READWRITE \
159
+ | G_PARAM_CONSTRUCT \
160
+ | G_PARAM_STATIC_NAME \
161
+ | G_PARAM_STATIC_NICK \
162
+ | G_PARAM_STATIC_BLURB)
164
+ g_object_class_install_property(gobject_class, PROP_SINGLE_CLICK,
165
+ g_param_spec_boolean("single-click",
169
+ XFDESKTOP_PARAM_FLAGS));
171
+#undef XFDESKTOP_PARAM_FLAGS
173
/* same binding entries as GtkIconView */
174
gtk_binding_entry_add_signal(binding_set, GDK_a, GDK_CONTROL_MASK,
176
@@ -643,6 +682,14 @@ xfdesktop_icon_view_init(XfdesktopIconView *icon_view)
177
g_object_set(G_OBJECT(icon_view), "has-tooltip", TRUE, NULL);
178
g_signal_connect(G_OBJECT(icon_view), "query-tooltip",
179
G_CALLBACK(xfdesktop_icon_view_show_tooltip), NULL);
181
+ icon_view->priv->channel = xfconf_channel_new (XFDESKTOP_CHANNEL);
183
+ xfconf_g_property_bind(icon_view->priv->channel,
184
+ "/desktop-icons/single-click",
186
+ G_OBJECT(icon_view),
189
GTK_WIDGET_SET_FLAGS(GTK_WIDGET(icon_view), GTK_NO_WINDOW);
191
@@ -664,11 +711,54 @@ xfdesktop_icon_view_finalize(GObject *obj)
192
g_list_foreach(icon_view->priv->pending_icons, (GFunc)g_object_unref, NULL);
193
g_list_free(icon_view->priv->pending_icons);
194
/* icon_view->priv->icons should be cleared in _unrealize() */
196
+ if (icon_view->priv->channel) {
197
+ g_object_unref (icon_view->priv->channel);
198
+ icon_view->priv->channel = NULL;
201
G_OBJECT_CLASS(xfdesktop_icon_view_parent_class)->finalize(obj);
205
+xfce_icon_view_set_property(GObject *object,
207
+ const GValue *value,
210
+ XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(object);
212
+ switch(property_id) {
213
+ case PROP_SINGLE_CLICK:
214
+ icon_view->priv->single_click = g_value_get_boolean (value);
218
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
224
+xfce_icon_view_get_property(GObject *object,
229
+ XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(object);
231
+ switch(property_id) {
232
+ case PROP_SINGLE_CLICK:
233
+ g_value_set_boolean(value, icon_view->priv->single_click);
237
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
243
xfdesktop_icon_view_add_move_binding(GtkBindingSet *binding_set,
246
@@ -808,6 +898,14 @@ xfdesktop_icon_view_button_press(GtkWidget *widget,
250
+xfdesktop_icon_view_get_single_click(XfdesktopIconView *icon_view)
252
+ g_return_val_if_fail(XFDESKTOP_IS_ICON_VIEW(icon_view), FALSE);
254
+ return icon_view->priv->single_click;
258
xfdesktop_icon_view_button_release(GtkWidget *widget,
261
@@ -816,6 +914,24 @@ xfdesktop_icon_view_button_release(GtkWidget *widget,
263
TRACE("entering btn=%d", evt->button);
266
+ if(xfdesktop_icon_view_get_single_click(icon_view)
267
+ && evt->button == 1
268
+ && !(evt->state & GDK_SHIFT_MASK)
269
+ && !(evt->state & GDK_CONTROL_MASK)
270
+ && !icon_view->priv->definitely_dragging
271
+ && !icon_view->priv->definitely_rubber_banding) {
272
+ XfdesktopIcon *icon;
273
+ GList *icon_l = g_list_find_custom(icon_view->priv->icons, evt,
274
+ (GCompareFunc)xfdesktop_check_icon_clicked);
275
+ if(icon_l && (icon = icon_l->data)) {
276
+ icon_view->priv->cursor = icon;
277
+ g_signal_emit(G_OBJECT(icon_view), __signals[SIG_ICON_ACTIVATED],
279
+ xfdesktop_icon_activated(icon);
283
if((evt->button == 3 || (evt->button == 1 && (evt->state & GDK_SHIFT_MASK))) &&
284
icon_view->priv->definitely_dragging == FALSE &&
285
icon_view->priv->definitely_rubber_banding == FALSE)
286
@@ -889,6 +1005,12 @@ xfdesktop_icon_view_focus_out(GtkWidget *widget,
287
xfdesktop_icon_view_invalidate_icon(icon_view, l->data, FALSE);
290
+ if(G_UNLIKELY(icon_view->priv->single_click)) {
291
+ if(G_LIKELY(icon_view->priv->parent_window->window != NULL)) {
292
+ gdk_window_set_cursor(icon_view->priv->parent_window->window, NULL);
299
@@ -1076,6 +1198,11 @@ xfdesktop_icon_view_motion_notify(GtkWidget *widget,
300
/* normal movement; highlight icons as they go under the pointer */
302
if(icon_view->priv->item_under_pointer) {
303
+ if(G_UNLIKELY(icon_view->priv->single_click)) {
304
+ GdkCursor *cursor = gdk_cursor_new(GDK_HAND2);
305
+ gdk_window_set_cursor(evt->window, cursor);
306
+ gdk_cursor_unref(cursor);
308
if(!xfdesktop_icon_get_extents(icon_view->priv->item_under_pointer,
309
NULL, NULL, &extents)
310
|| !xfdesktop_rectangle_contains_point(&extents, evt->x, evt->y))
311
@@ -1087,6 +1214,9 @@ xfdesktop_icon_view_motion_notify(GtkWidget *widget,
315
+ if(G_UNLIKELY(icon_view->priv->single_click)) {
316
+ gdk_window_set_cursor(evt->window, NULL);
318
icon = xfdesktop_icon_view_widget_coords_to_item(icon_view,
321
@@ -1122,6 +1252,12 @@ xfdesktop_icon_view_leave_notify(GtkWidget *widget,
322
xfdesktop_icon_view_invalidate_icon(icon_view, icon, FALSE);
326
+ if(G_UNLIKELY(icon_view->priv->single_click)) {
327
+ if(GTK_WIDGET_REALIZED(widget)) {
328
+ gdk_window_set_cursor(widget->window, NULL);