Codebase list xapp / 8c0d76b
status icon: Add support for scroll events ref: https://github.com/linuxmint/cinnamon/issues/9152 Michael Webster 2 years ago
12 changed file(s) with 248 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
136136 gir = gnome.generate_gir(libxapp,
137137 namespace: 'XApp',
138138 nsversion: '1.0',
139 sources: xapp_headers + xapp_sources + dbus_headers,
139 sources: xapp_headers + xapp_sources + dbus_headers + xapp_enums,
140140 identifier_prefix: 'XApp',
141141 symbol_prefix: 'xapp_',
142142 includes: ['GObject-2.0', 'Gtk-3.0'],
1616 <arg name='time' direction='in' type='u'/>
1717 <arg name='panel_position' direction='in' type='i'/>
1818 </method>
19 <method name='Scroll'>
20 <arg name='delta' direction='in' type='i'/>
21 <arg name='orientation' direction='in' type='i'/>
22 <arg name='time' direction='in' type='u'/>
23 </method>
1924 <property type='s' name='Name' access='read'/>
2025 <property type='s' name='IconName' access='read'/>
2126 <property type='s' name='TooltipText' access='read'/>
3636 BUTTON_RELEASE,
3737 ACTIVATE,
3838 STATE_CHANGED,
39 SCROLL,
3940 LAST_SIGNAL
4041 };
4142
157158 return "Fallback";
158159 case XAPP_STATUS_ICON_STATE_NO_SUPPORT:
159160 return "NoSupport";
161 default:
162 return "Unknown";
163 }
164 }
165
166 static const gchar *
167 direction_to_str (XAppScrollDirection direction)
168 {
169 switch (direction)
170 {
171 case XAPP_SCROLL_UP:
172 return "Up";
173 case XAPP_SCROLL_DOWN:
174 return "Down";
175 case XAPP_SCROLL_LEFT:
176 return "Left";
177 case XAPP_SCROLL_RIGHT:
178 return "Right";
160179 default:
161180 return "Unknown";
162181 }
437456 return TRUE;
438457 }
439458
459 static gboolean
460 handle_scroll_method (XAppStatusIconInterface *skeleton,
461 GDBusMethodInvocation *invocation,
462 gint delta,
463 XAppScrollDirection direction,
464 guint _time,
465 XAppStatusIcon *icon)
466 {
467 g_debug ("XAppStatusIcon: received Scroll from monitor %s: "
468 "delta: %d , direction: %s , time: %u",
469 g_dbus_method_invocation_get_sender (invocation),
470 delta, direction_to_str (direction), _time);
471
472 g_signal_emit(icon, signals[SCROLL], 0,
473 delta,
474 direction,
475 _time);
476
477 xapp_status_icon_interface_complete_scroll (skeleton,
478 invocation);
479
480 return TRUE;
481 }
482
440483 static void
441484 popup_gtk_status_icon_with_menu (XAppStatusIcon *icon,
442485 GtkMenu *menu,
723766 static SkeletonSignal skeleton_signals[] = {
724767 // signal name callback
725768 { "handle-button-press", handle_click_method },
726 { "handle-button-release", handle_click_method }
769 { "handle-button-release", handle_click_method },
770 { "handle-scroll", handle_scroll_method }
727771 };
728772
729773 static gboolean
13431387 0,
13441388 NULL, NULL, NULL,
13451389 G_TYPE_NONE, 1, XAPP_TYPE_STATUS_ICON_STATE);
1390
1391 /**
1392 * XAppStatusIcon::scroll-event:
1393 * @icon: The #XAppStatusIcon
1394 * @amount: The amount of movement for the scroll event
1395 * @direction: the #XAppScrollDirection of the scroll event
1396 * @time: The time supplied by the event, or 0
1397 *
1398 * Gets emitted when the user uses the mouse scroll wheel over the status icon.
1399 * For the most part, amounts will always be 1, unless an applet supports smooth
1400 * scrolling. Generally the direction value is most important.
1401 */
1402 signals [SCROLL] =
1403 g_signal_new ("scroll-event",
1404 XAPP_TYPE_STATUS_ICON,
1405 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
1406 0,
1407 NULL, NULL, NULL,
1408 G_TYPE_NONE, 3, G_TYPE_INT, XAPP_TYPE_SCROLL_DIRECTION, G_TYPE_UINT);
13461409 }
13471410
13481411 /**
2727 XAPP_STATUS_ICON_STATE_NO_SUPPORT
2828 } XAppStatusIconState;
2929
30 /**
31 * XAppScrollDirection:
32 * @XAPP_SCROLL_UP: Scroll theoretical content up.
33 * @XAPP_SCROLL_DOWN: Scroll theoretical content down.
34 * @XAPP_SCROLL_LEFT: Scroll theoretical content left.
35 * @XAPP_SCROLL_RIGHT: Scroll theoretical content right.
36 *
37 * Represents the direction of icon scroll events.
38 */
39 typedef enum
40 {
41 XAPP_SCROLL_UP,
42 XAPP_SCROLL_DOWN,
43 XAPP_SCROLL_LEFT,
44 XAPP_SCROLL_RIGHT
45 } XAppScrollDirection;
46
47
3048 XAppStatusIcon *xapp_status_icon_new (void);
3149 void xapp_status_icon_set_name (XAppStatusIcon *icon, const gchar *name);
3250 void xapp_status_icon_set_icon_name (XAppStatusIcon *icon, const gchar *icon_name);
6666 # this is the bus owned name
6767 self.name = self.proxy.get_name()
6868
69 self.add_events(Gdk.EventMask.SCROLL_MASK)
70
6971 # this is (usually) the name of the remote process
7072 self.proc_name = self.proxy.props.name
7173
98100
99101 self.connect("button-press-event", self.on_button_press)
100102 self.connect("button-release-event", self.on_button_release)
103 self.connect("scroll-event", self.on_scroll)
101104 self.connect("enter-notify-event", self.on_enter_notify)
102105 self.connect("leave-notify-event", self.on_leave_notify)
103106
217220 GObject.timeout_add(200, self.after_release_idle)
218221
219222 return Gdk.EVENT_PROPAGATE
223
224 def on_scroll(self, widget, event):
225 has, direction = event.get_scroll_direction()
226
227 x_dir = XApp.ScrollDirection.UP
228 delta = 0
229
230 if direction != Gdk.ScrollDirection.SMOOTH:
231 x_dir = XApp.ScrollDirection(int(direction))
232
233 if direction == Gdk.ScrollDirection.UP:
234 delta = -1
235 elif direction == Gdk.ScrollDirection.DOWN:
236 delta = 1
237 elif direction == Gdk.ScrollDirection.LEFT:
238 delta = -1
239 elif direction == Gdk.ScrollDirection.RIGHT:
240 delta = 1
241
242 self.proxy.call_scroll_sync(delta, x_dir, event.time, None)
220243
221244 def calc_menu_origin(self, widget, orientation):
222245 alloc = widget.get_allocation()
11 import gi
22 gi.require_version('Gtk', '3.0')
33 gi.require_version('XApp', '1.0')
4 from gi.repository import Gio, GLib, GObject, Gtk, XApp
4 from gi.repository import Gio, GLib, GObject, Gtk, XApp, Gdk
55 import os
66 import sys
77
1515
1616 self.proxy = icon
1717 self.name = self.proxy.get_name()
18 self.add_events(Gdk.EventMask.SCROLL_MASK)
1819
1920 box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
2021
3940
4041 self.connect("button-press-event", self.on_button_press)
4142 self.connect("button-release-event", self.on_button_release)
43 self.connect("scroll-event", self.on_scroll)
4244
4345 def on_icon_name_changed(self, proxy, gparamspec, data=None):
4446 string = self.proxy.props.icon_name
7577 time = event.time
7678 print ("Button release : %d:%d" % (x, y))
7779 self.proxy.call_button_release_sync(x, y, event.button, event.time, Gtk.PositionType.TOP, None)
80
81 def on_scroll(self, widget, event):
82 has, direction = event.get_scroll_direction()
83
84 x_dir = XApp.ScrollDirection.UP
85 delta = 0
86
87 if direction != Gdk.ScrollDirection.SMOOTH:
88 x_dir = XApp.ScrollDirection(int(direction))
89
90 if direction == Gdk.ScrollDirection.UP:
91 delta = -1
92 elif direction == Gdk.ScrollDirection.DOWN:
93 delta = 1
94 elif direction == Gdk.ScrollDirection.LEFT:
95 delta = -1
96 elif direction == Gdk.ScrollDirection.RIGHT:
97 delta = 1
98
99 print ("Scroll : delta: %d, orientation: %d" % (delta, x_dir))
100 self.proxy.call_scroll_sync(delta, x_dir, event.time, None)
78101
79102 class StatusApplet(GObject.Object):
80103
2121 self.status_icon.set_tooltip_text("Testing primary activate and secondary menu")
2222 self.status_icon.set_label("label 1")
2323 self.status_icon.set_visible(True)
24 self.status_icon.connect("scroll-event", self.handle_scroll_event)
25
26 self.label = None
27 self.window = None
2428
2529 self.counter = 1
2630
4751 print("Activated via button %d" % button)
4852 self.counter = 0
4953 self.status_icon.set_label("label %d" % self.counter)
54 self.make_window()
55
56 def make_window(self):
57 w = Gtk.Window(default_width=300, default_height=130)
58 b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
59 w.add(b)
60 self.label = Gtk.Label("How can I help you?")
61 b.pack_start(self.label, True, True, 0)
62
63 self.window = w
64 w.show_all()
65
66 def handle_scroll_event(self, icon, amount, orientation, time, data=None):
67 if self.window == None:
68 self.make_window()
69
70 if orientation == XApp.ScrollDirection.UP:
71 self.label.set_text("Scrolled Up !")
72 elif orientation == XApp.ScrollDirection.DOWN:
73 self.label.set_text("Scrolled Down!")
74 elif orientation == XApp.ScrollDirection.LEFT:
75 self.label.set_text("Scrolled Left!")
76 else:
77 self.label.set_text("Scrolled Right!")
78
5079
5180 if __name__ == '__main__':
5281 GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
1616 class App(GObject.Object):
1717 def __init__(self):
1818 super(App, self).__init__()
19 self.window = None
20
1921 self.indicator = AppIndicator3.Indicator.new("xapp-status-icon-via-libappindicator",
2022 "info",
2123 AppIndicator3.IndicatorCategory.SYSTEM_SERVICES)
3840
3941 self.indicator.set_menu(self.menu)
4042
43 self.indicator.connect("scroll-event", self.handle_scroll_event)
4144 GLib.timeout_add_seconds(2, self.on_timeout_cb)
4245
4346 def activate_window(self, item, data=None):
4447 w = Gtk.Window(default_width=300, default_height=130)
4548 b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
4649 w.add(b)
47 b.pack_start(Gtk.Label("How can I help you?"), True, True, 0)
50 self.label = Gtk.Label("How can I help you?")
51 b.pack_start(self.label, True, True, 0)
52
53 self.window = w
4854 w.show_all()
55
56 def handle_scroll_event(self, icon, amount, direction, data=None):
57 if self.window == None:
58 self.activate_window(None)
59
60 if direction == Gdk.ScrollDirection.UP:
61 self.label.set_text("Scrolled Up!")
62 elif direction == Gdk.ScrollDirection.DOWN:
63 self.label.set_text("Scrolled Down!")
64 elif direction == Gdk.ScrollDirection.LEFT:
65 self.label.set_text("Scrolled Left!")
66 else:
67 self.label.set_text("Scrolled Right!")
4968
5069 def on_timeout_cb(self):
5170 self.counter += 1
2121 self.status_icon.set_tooltip_text("Testing primary and secondary menus")
2222 self.status_icon.set_label("label 1")
2323 self.status_icon.set_visible(True)
24 self.status_icon.connect("scroll-event", self.handle_scroll_event)
2425
2526 self.counter = 1
27
28 self.label = None
29 self.window = None
2630
2731 menu = Gtk.Menu()
2832 menu.append(Gtk.MenuItem.new_with_label("Engage the hyperdrive"))
5054 self.status_icon.set_label("label %d" % self.counter)
5155 return True
5256
57 def make_window(self):
58 w = Gtk.Window(default_width=300, default_height=130)
59 b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
60 w.add(b)
61 self.label = Gtk.Label("How can I help you?")
62 b.pack_start(self.label, True, True, 0)
63
64 self.window = w
65 w.show_all()
66
67 def handle_scroll_event(self, icon, amount, orientation, time, data=None):
68 if self.window == None:
69 self.make_window()
70
71 if orientation == XApp.ScrollDirection.UP:
72 self.label.set_text("Scrolled Up !")
73 elif orientation == XApp.ScrollDirection.DOWN:
74 self.label.set_text("Scrolled Down!")
75 elif orientation == XApp.ScrollDirection.LEFT:
76 self.label.set_text("Scrolled Left!")
77 else:
78 self.label.set_text("Scrolled Right!")
79
5380 if __name__ == '__main__':
5481 GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
5582 app = App()
2222 self.status_icon.set_label("label 1")
2323 self.status_icon.set_visible(True)
2424
25 self.label = None
26 self.window = None
27
2528 self.counter = 1
2629
2730 self.status_icon.connect("activate", self.on_status_icon_activate)
31 self.status_icon.connect("scroll-event", self.handle_scroll_event)
2832
2933 GLib.timeout_add_seconds(2, self.on_timeout_cb)
3034
4044 print("Activated via button %d" % button)
4145 self.counter = 0
4246 self.status_icon.set_label("label %d" % self.counter)
47 self.make_window()
48
49 def make_window(self):
50 w = Gtk.Window(default_width=300, default_height=130)
51 b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
52 w.add(b)
53 self.label = Gtk.Label("How can I help you?")
54 b.pack_start(self.label, True, True, 0)
55
56 self.window = w
57 w.show_all()
58
59 def handle_scroll_event(self, icon, amount, orientation, time, data=None):
60 if self.window == None:
61 self.make_window()
62
63 if orientation == XApp.ScrollDirection.UP:
64 self.label.set_text("Scrolled Up !")
65 elif orientation == XApp.ScrollDirection.DOWN:
66 self.label.set_text("Scrolled Down!")
67 elif orientation == XApp.ScrollDirection.LEFT:
68 self.label.set_text("Scrolled Left!")
69 else:
70 self.label.set_text("Scrolled Right!")
4371
4472 if __name__ == '__main__':
4573 GLib.setenv ("G_MESSAGES_DEBUG", "all", True)
4545 self.xapp_icon.connect("activate", self.on_xapp_icon_activated)
4646 self.xapp_icon.connect("button-press-event", self.on_xapp_button_pressed)
4747 self.xapp_icon.connect("button-release-event", self.on_xapp_button_released)
48 self.xapp_icon.connect("scroll-event", self.on_xapp_scroll_event)
4849 self.xapp_icon.connect("state-changed", self.xapp_icon_state_changed);
4950
5051 def xapp_icon_state_changed(self, state, data=None):
8283 def on_xapp_button_released(self, icon, x, y, button, _time, panel_position):
8384 if not self.gtk_menu:
8485 self.sn_item.show_context_menu(button, x, y)
86
87 def on_xapp_scroll_event(self, icon, delta, direction, _time):
88 o_str = "horizontal" if direction in (XApp.ScrollDirection.LEFT, XApp.ScrollDirection.RIGHT) else "vertical"
89
90 self.sn_item.scroll(delta, o_str)
8591
8692 def update_menu(self):
8793 # print("ItemIsMenu: ", self.sn_item.item_is_menu())
169169 if button == Gdk.BUTTON_SECONDARY:
170170 self.sn_item_proxy.call_context_menu(x, y, None, None)
171171
172 def scroll(self, delta, o_str):
173 self.sn_item_proxy.call_scroll(delta, o_str, None, None)
174
172175 def destroy(self):
173176 try:
174177 self.sn_item_proxy.disconnect_by_func(self.signal_received)