mate-xapp-status-applet.py: Make improvements to event handling and
widget appearance during clicks.
Michael Webster
4 years ago
19 | 19 | locale.bindtextdomain("xapp", "@locale@") |
20 | 20 | locale.textdomain("xapp") |
21 | 21 | |
22 | INDICATOR_BOX_BORDER = 1 | |
23 | INDICATOR_BOX_BORDER_COMP = INDICATOR_BOX_BORDER + 1 | |
24 | ICON_SIZE_REDUCTION = (INDICATOR_BOX_BORDER * 2) | |
25 | ICON_SPACING = 5 | |
22 | ICON_SIZE_REDUCTION = 2 | |
26 | 23 | VISIBLE_LABEL_MARGIN = 5 # When an icon has a label, add a margin between icon and label |
27 | 24 | |
28 | 25 | statusicon_css_string = """ |
29 | .statuswidget { | |
26 | .statuswidget-horizontal { | |
30 | 27 | border: none; |
31 | 28 | padding-top: 0; |
32 | padding-left: 4px; | |
29 | padding-left: 2px; | |
33 | 30 | padding-bottom: 0; |
34 | padding-right: 4px; | |
31 | padding-right: 2px; | |
32 | } | |
33 | ||
34 | .statuswidget-vertical { | |
35 | border: none; | |
36 | padding-top: 2px; | |
37 | padding-left: 0; | |
38 | padding-bottom: 2px; | |
39 | padding-right: 0; | |
35 | 40 | } |
36 | 41 | """ |
37 | 42 | |
46 | 51 | elif mate_applet_orientation == MatePanelApplet.AppletOrient.RIGHT: |
47 | 52 | return Gtk.PositionType.LEFT |
48 | 53 | |
49 | class StatusWidget(Gtk.Button): | |
54 | class StatusWidget(Gtk.ToggleButton): | |
50 | 55 | def __init__(self, icon, orientation, size): |
51 | 56 | super(Gtk.Button, self).__init__() |
52 | 57 | self.theme = Gtk.IconTheme.get_default() |
53 | 58 | self.orientation = orientation |
54 | 59 | self.size = size |
55 | 60 | |
56 | self.get_style_context().add_class("statuswidget") | |
57 | ||
58 | 61 | self.proxy = icon |
59 | 62 | |
60 | 63 | # this is the bus owned name |
68 | 71 | self.image = Gtk.Image(hexpand=True) |
69 | 72 | self.image.show() |
70 | 73 | self.label = Gtk.Label(no_show_all=True) |
71 | self.box.pack_start(self.image, False, False, 0) | |
74 | self.box.pack_start(self.image, True, False, 0) | |
72 | 75 | self.box.pack_start(self.label, False, False, 0) |
73 | 76 | self.add(self.box) |
77 | ||
78 | self.set_can_default(False) | |
79 | self.set_can_focus(False) | |
80 | self.set_relief(Gtk.ReliefStyle.NONE) | |
81 | self.set_focus_on_click(False) | |
74 | 82 | |
75 | 83 | flags = GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE |
76 | 84 | |
102 | 110 | |
103 | 111 | self.set_icon(string) |
104 | 112 | |
113 | def update_style(self, orientation): | |
114 | ctx = self.get_style_context() | |
115 | ||
116 | if orientation == Gtk.Orientation.HORIZONTAL: | |
117 | ctx.remove_class("statuswidget-vertical") | |
118 | ctx.add_class("statuswidget-horizontal") | |
119 | else: | |
120 | ctx.remove_class("statuswidget-horizontal") | |
121 | ctx.add_class("statuswidget-vertical") | |
122 | ||
105 | 123 | def update_orientation(self): |
106 | box_orientation = Gtk.Orientation.HORIZONTAL | |
107 | ||
108 | if self.orientation in (MatePanelApplet.AppletOrient.LEFT, MatePanelApplet.AppletOrient.RIGHT): | |
124 | if self.orientation in (MatePanelApplet.AppletOrient.UP, MatePanelApplet.AppletOrient.DOWN): | |
125 | box_orientation = Gtk.Orientation.HORIZONTAL | |
126 | else: | |
109 | 127 | box_orientation = Gtk.Orientation.VERTICAL |
110 | 128 | |
129 | self.update_style(box_orientation) | |
111 | 130 | self.box.set_orientation(box_orientation) |
112 | 131 | |
113 | 132 | if len(self.label.props.label) > 0 and box_orientation == Gtk.Orientation.HORIZONTAL: |
119 | 138 | |
120 | 139 | def set_icon(self, string): |
121 | 140 | size = self.size - ICON_SIZE_REDUCTION |
122 | ||
123 | # round down to even | |
124 | if size % 2 != 0: | |
125 | size -= 1 | |
126 | 141 | |
127 | 142 | self.image.set_pixel_size(size) |
128 | 143 | |
157 | 172 | return Gdk.EVENT_PROPAGATE |
158 | 173 | # /TODO |
159 | 174 | |
175 | def after_release_idle(self, data=None): | |
176 | self.set_active(False) | |
177 | ||
178 | return GLib.SOURCE_REMOVE | |
179 | ||
160 | 180 | def on_button_press(self, widget, event): |
161 | 181 | orientation = translate_applet_orientation_to_xapp(self.orientation) |
162 | 182 | |
163 | 183 | x, y = self.calc_menu_origin(widget, orientation) |
164 | 184 | self.proxy.call_button_press(x, y, event.button, event.time, orientation, None, None) |
165 | 185 | |
166 | self.set_state_flags(Gtk.StateFlags.SELECTED, False) | |
167 | ||
168 | if event.button == 3: | |
186 | if event.button != Gdk.BUTTON_PRIMARY: | |
187 | self.set_active(True) | |
188 | ||
189 | if event.button in (Gdk.BUTTON_MIDDLE, Gdk.BUTTON_SECONDARY): | |
190 | # Block the 'remove from panel' menu, and the middle-click drag. | |
191 | # They can still accomplish these things along the edges of the applet | |
169 | 192 | return Gdk.EVENT_STOP |
170 | 193 | |
171 | 194 | return Gdk.EVENT_PROPAGATE |
175 | 198 | |
176 | 199 | x, y = self.calc_menu_origin(widget, orientation) |
177 | 200 | self.proxy.call_button_release(x, y, event.button, event.time, orientation, None, None) |
178 | self.set_state_flags(Gtk.StateFlags.SELECTED, False) | |
179 | ||
180 | if event.button == 3: | |
181 | return Gdk.EVENT_STOP | |
201 | ||
202 | GObject.timeout_add(200, self.after_release_idle) | |
182 | 203 | |
183 | 204 | return Gdk.EVENT_PROPAGATE |
184 | 205 | |
190 | 211 | |
191 | 212 | if orientation == Gtk.PositionType.TOP: |
192 | 213 | rx = x + alloc.x |
193 | ry = y + alloc.y + alloc.height + INDICATOR_BOX_BORDER_COMP | |
214 | ry = y + alloc.y + alloc.height | |
194 | 215 | elif orientation == Gtk.PositionType.BOTTOM: |
195 | 216 | rx = x + alloc.x |
196 | ry = y + alloc.y - INDICATOR_BOX_BORDER_COMP | |
217 | ry = y + alloc.y | |
197 | 218 | elif orientation == Gtk.PositionType.LEFT: |
198 | rx = x + alloc.x + alloc.width + INDICATOR_BOX_BORDER_COMP | |
219 | rx = x + alloc.x + alloc.width | |
199 | 220 | ry = y + alloc.y |
200 | 221 | elif orientation == Gtk.PositionType.RIGHT: |
201 | rx = x + alloc.x - INDICATOR_BOX_BORDER_COMP | |
222 | rx = x + alloc.x | |
202 | 223 | ry = y + alloc.y |
203 | 224 | else: |
204 | 225 | rx = x |
209 | 230 | class MateXAppStatusApplet(object): |
210 | 231 | def __init__(self, applet, iid): |
211 | 232 | self.applet = applet |
212 | self.applet.set_flags(MatePanelApplet.AppletFlags.EXPAND_MINOR) | |
233 | self.applet.set_flags(MatePanelApplet.AppletFlags.EXPAND_MINOR | | |
234 | MatePanelApplet.AppletFlags.HAS_HANDLE) | |
213 | 235 | self.applet.set_can_focus(False) |
214 | 236 | self.applet.set_background_widget(self.applet) |
215 | 237 | |
225 | 247 | self.monitor = None |
226 | 248 | |
227 | 249 | def on_applet_realized(self, widget, data=None): |
228 | self.indicator_box = Gtk.Box(spacing=ICON_SPACING, | |
229 | visible=True, | |
230 | border_width=INDICATOR_BOX_BORDER) | |
250 | self.indicator_box = Gtk.Box(visible=True) | |
231 | 251 | |
232 | 252 | self.applet.add(self.indicator_box) |
233 | 253 | self.applet.connect("change-size", self.on_applet_size_changed) |