Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 724986 | Differences between
and this patch

Collapse All | Expand All

(-)a/README.rst (+8 lines)
Lines 19-24 Link Here
19
- Switch for visible shift and modifier sequences only
19
- Switch for visible shift and modifier sequences only
20
- Repeats compression
20
- Repeats compression
21
- Countless bug fixes
21
- Countless bug fixes
22
- Mouse buttons support
22
23
23
24
24
Installation and basic usage
25
Installation and basic usage
Lines 150-155 Link Here
150
  requested threshold. A counter of total occurrences is shown instead,
151
  requested threshold. A counter of total occurrences is shown instead,
151
  which is generally more legible.
152
  which is generally more legible.
152
153
154
Show mouse:
155
  When enabled, the mouse buttons are shown on the left of the output window.
156
157
Hide duration:
158
  Duration (in seconds) of the fade-out animation when a button is released.
159
  Defaults to 1 second.
160
153
161
154
Advanced usage
162
Advanced usage
155
--------------
163
--------------
(-)a/Screenkey/inputlistener.py (-6 / +27 lines)
Lines 155-160 Link Here
155
        self.modifiers = modifiers
155
        self.modifiers = modifiers
156
156
157
157
158
class ButtonData():
159
    def __init__(self, btn, pressed):
160
        self.btn = btn
161
        self.pressed = pressed == xlib.ButtonPress
162
163
158
class InputType:
164
class InputType:
159
    keyboard = 0b001
165
    keyboard = 0b001
160
    button   = 0b010
166
    button   = 0b010
Lines 164-172 Link Here
164
170
165
171
166
class InputListener(threading.Thread):
172
class InputListener(threading.Thread):
167
    def __init__(self, callback, input_types=InputType.all, kbd_compose=True, kbd_translate=True):
173
    def __init__(self, kbd_callback, btn_callback, input_types=InputType.all,
174
                 kbd_compose=True, kbd_translate=True):
168
        super(InputListener, self).__init__()
175
        super(InputListener, self).__init__()
169
        self.callback = callback
176
        self.kbd_callback = kbd_callback
177
        self.btn_callback = btn_callback
170
        self.input_types = input_types
178
        self.input_types = input_types
171
        self.kbd_compose = kbd_compose
179
        self.kbd_compose = kbd_compose
172
        self.kbd_translate = kbd_translate
180
        self.kbd_translate = kbd_translate
Lines 189-203 Link Here
189
            xlib.XSendEvent(self.replay_dpy, self.replay_win, False, 0, fwd_ev)
197
            xlib.XSendEvent(self.replay_dpy, self.replay_win, False, 0, fwd_ev)
190
198
191
199
192
    def _event_callback(self, data):
200
    def _kbd_event_callback(self, data):
193
        self.callback(data)
201
        self.kbd_callback(data)
202
        return False
203
204
    def _btn_event_callback(self, data):
205
        self.btn_callback(data)
194
        return False
206
        return False
195
207
196
    def _event_processed(self, data):
208
    def _event_processed(self, data):
197
        data.symbol = xlib.XKeysymToString(data.keysym)
209
        data.symbol = xlib.XKeysymToString(data.keysym)
198
        if data.string is None:
210
        if data.string is None:
199
            data.string = keysym_to_unicode(data.keysym)
211
            data.string = keysym_to_unicode(data.keysym)
200
        glib.idle_add(self._event_callback, data)
212
        glib.idle_add(self._kbd_event_callback, data)
201
213
202
214
203
    def _event_modifiers(self, kev, data):
215
    def _event_modifiers(self, kev, data):
Lines 314-319 Link Here
314
        self._kbd_last_ev = ev
326
        self._kbd_last_ev = ev
315
327
316
328
329
    def _btn_process(self, ev):
330
        if ev.type in [xlib.ButtonPress, xlib.ButtonRelease]:
331
            data = ButtonData(ev.xbutton.button, ev.type)
332
            glib.idle_add(self._btn_event_callback, data)
333
334
317
    def run(self):
335
    def run(self):
318
        # control connection
336
        # control connection
319
        self.control_dpy = xlib.XOpenDisplay(None)
337
        self.control_dpy = xlib.XOpenDisplay(None)
Lines 336-342 Link Here
336
            xlib.XCloseDisplay(self.replay_dpy)
354
            xlib.XCloseDisplay(self.replay_dpy)
337
355
338
            # cheap wakeup() equivalent for compatibility
356
            # cheap wakeup() equivalent for compatibility
339
            glib.idle_add(self._event_callback, None)
357
            glib.idle_add(self._kbd_event_callback, None)
358
            glib.idle_add(self._btn_event_callback, None)
340
359
341
            self.stopped = True
360
            self.stopped = True
342
            self.lock.release()
361
            self.lock.release()
Lines 385-390 Link Here
385
                xlib.XNextEvent(self.replay_dpy, xlib.byref(ev))
404
                xlib.XNextEvent(self.replay_dpy, xlib.byref(ev))
386
                if self.input_types & InputType.keyboard:
405
                if self.input_types & InputType.keyboard:
387
                    self._kbd_process(ev)
406
                    self._kbd_process(ev)
407
                if self.input_types & InputType.button:
408
                    self._btn_process(ev)
388
409
389
        # finalize
410
        # finalize
390
        self.lock.acquire()
411
        self.lock.acquire()
(-)a/Screenkey/labelmanager.py (-5 / +25 lines)
Lines 21-26 Link Here
21
ReplData = namedtuple('ReplData', ['value', 'font', 'suffix'])
21
ReplData = namedtuple('ReplData', ['value', 'font', 'suffix'])
22
KeyRepl  = namedtuple('KeyRepl',  ['bk_stop', 'silent', 'spaced', 'repl'])
22
KeyRepl  = namedtuple('KeyRepl',  ['bk_stop', 'silent', 'spaced', 'repl'])
23
KeyData  = namedtuple('KeyData',  ['stamp', 'is_ctrl', 'bk_stop', 'silent', 'spaced', 'markup'])
23
KeyData  = namedtuple('KeyData',  ['stamp', 'is_ctrl', 'bk_stop', 'silent', 'spaced', 'markup'])
24
ButtonData = namedtuple('ButtonData',  ['stamp', 'btn', 'pressed'])
24
25
25
REPLACE_SYMS = {
26
REPLACE_SYMS = {
26
    # Regular keys
27
    # Regular keys
Lines 140-152 Link Here
140
141
141
142
142
class LabelManager(object):
143
class LabelManager(object):
143
    def __init__(self, listener, logger, key_mode, bak_mode, mods_mode, mods_only,
144
    def __init__(self, label_listener, image_listener, logger, key_mode,
144
                 multiline, vis_shift, vis_space, recent_thr, compr_cnt, ignore, pango_ctx):
145
                 bak_mode, mods_mode, mods_only, multiline, vis_shift,
146
                 vis_space, recent_thr, compr_cnt, ignore, pango_ctx):
145
        self.key_mode = key_mode
147
        self.key_mode = key_mode
146
        self.bak_mode = bak_mode
148
        self.bak_mode = bak_mode
147
        self.mods_mode = mods_mode
149
        self.mods_mode = mods_mode
148
        self.logger = logger
150
        self.logger = logger
149
        self.listener = listener
151
        self.label_listener = label_listener
152
        self.image_listener = image_listener
150
        self.data = []
153
        self.data = []
151
        self.enabled = True
154
        self.enabled = True
152
        self.mods_only = mods_only
155
        self.mods_only = mods_only
Lines 169-175 Link Here
169
        self.stop()
172
        self.stop()
170
        compose = (self.key_mode == 'composed')
173
        compose = (self.key_mode == 'composed')
171
        translate = (self.key_mode in ['composed', 'translated'])
174
        translate = (self.key_mode in ['composed', 'translated'])
172
        self.kl = InputListener(self.key_press, InputType.keyboard, compose, translate)
175
        self.kl = InputListener(self.key_press, self.btn_press,
176
                                InputType.keyboard | InputType.button, compose,
177
                                translate)
173
        self.kl.start()
178
        self.kl.start()
174
        self.logger.debug("Thread started.")
179
        self.logger.debug("Thread started.")
175
180
Lines 278-284 Link Here
278
        if recent:
283
        if recent:
279
            markup += '</u>'
284
            markup += '</u>'
280
        self.logger.debug("Label updated: %s." % repr(markup))
285
        self.logger.debug("Label updated: %s." % repr(markup))
281
        self.listener(markup)
286
        self.label_listener(markup)
282
287
283
288
284
    def key_press(self, event):
289
    def key_press(self, event):
Lines 463-465 Link Here
463
            value = event.string or symbol
468
            value = event.string or symbol
464
        self.data.append(KeyData(datetime.now(), True, True, True, True, value))
469
        self.data.append(KeyData(datetime.now(), True, True, True, True, value))
465
        return True
470
        return True
471
472
473
    def btn_press(self, event):
474
        if not self.enabled:
475
            return False
476
477
        if event.pressed:
478
            action = "pressed"
479
        else:
480
            action = "released"
481
        self.logger.debug("Mouse button %d %s" % (event.btn, action))
482
483
        self.image_listener(
484
            ButtonData(datetime.now(), event.btn, event.pressed)
485
        )
(-)a/Screenkey/screenkey.py (-12 / +180 lines)
Lines 7-15 Link Here
7
from .labelmanager import LabelManager
7
from .labelmanager import LabelManager
8
8
9
from threading import Timer
9
from threading import Timer
10
from datetime import datetime
10
import json
11
import json
11
import os
12
import os
12
import subprocess
13
import subprocess
14
from tempfile import NamedTemporaryFile
13
15
14
import gi
16
import gi
15
# gi.require_version('Gtk', '2.0')
17
# gi.require_version('Gtk', '2.0')
Lines 19-25 Link Here
19
from gi.repository import GLib
21
from gi.repository import GLib
20
GLib.threads_init()
22
GLib.threads_init()
21
23
22
from gi.repository import Gtk, Gdk, Pango
24
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango
23
import cairo
25
import cairo
24
26
25
27
Lines 35-40 Link Here
35
VERTICAL = Gtk.Orientation.VERTICAL
37
VERTICAL = Gtk.Orientation.VERTICAL
36
IF_VALID = Gtk.SpinButtonUpdatePolicy.IF_VALID
38
IF_VALID = Gtk.SpinButtonUpdatePolicy.IF_VALID
37
39
40
BUTTONS_SVG = None
41
42
def load_button_pixbufs(color):
43
    global BUTTONS_SVG
44
45
    if BUTTONS_SVG is None:
46
        with open('/usr/share/images/screenkey/mouse.svg', 'r') as svg_file:
47
            BUTTONS_SVG = svg_file.readlines()
48
49
    if not isinstance(color, str):
50
        # Gdk.Color
51
        color = 'rgb({}, {}, {})'.format(
52
            round(color.red_float * 255),
53
            round(color.green_float * 255),
54
            round(color.blue_float * 255)
55
        )
56
    button_pixbufs = []
57
    svg = NamedTemporaryFile(mode='w', suffix='.svg')
58
    for line in BUTTONS_SVG[1:-1]:
59
        svg.seek(0)
60
        svg.truncate()
61
        svg.writelines((
62
            BUTTONS_SVG[0],
63
            line.replace('#fff', color),
64
            BUTTONS_SVG[-1],
65
        ))
66
        svg.flush()
67
        os.fsync(svg.fileno())
68
        button_pixbufs.append(GdkPixbuf.Pixbuf.new_from_file(svg.name))
69
    svg.close()
70
    return button_pixbufs
71
38
72
39
class Screenkey(Gtk.Window):
73
class Screenkey(Gtk.Window):
40
    STATE_FILE = os.path.join(GLib.get_user_config_dir(), 'screenkey.json')
74
    STATE_FILE = os.path.join(GLib.get_user_config_dir(), 'screenkey.json')
Lines 67-73 Link Here
67
                            'vis_shift': False,
101
                            'vis_shift': False,
68
                            'vis_space': True,
102
                            'vis_space': True,
69
                            'geometry': None,
103
                            'geometry': None,
70
                            'screen': 0})
104
                            'screen': 0,
105
                            'mouse': False,
106
                            'button_hide_duration': 1})
71
        self.options = self.load_state()
107
        self.options = self.load_state()
72
        if self.options is None:
108
        if self.options is None:
73
            self.options = defaults
109
            self.options = defaults
Lines 87-101 Link Here
87
        self.set_focus_on_map(False)
123
        self.set_focus_on_map(False)
88
        self.set_app_paintable(True)
124
        self.set_app_paintable(True)
89
125
126
        self.button_pixbufs = []
127
        self.button_states = [None] * 8
128
        self.img = Gtk.Image()
129
        self.update_image_tag = None
130
131
        self.box = Gtk.HBox(homogeneous=False)
132
        self.box.show()
133
        self.add(self.box)
134
90
        self.label = Gtk.Label()
135
        self.label = Gtk.Label()
91
        self.label.set_attributes(Pango.AttrList())
136
        self.label.set_attributes(Pango.AttrList())
92
        self.label.set_ellipsize(Pango.EllipsizeMode.START)
137
        self.label.set_ellipsize(Pango.EllipsizeMode.START)
93
        self.label.set_justify(Gtk.Justification.CENTER)
138
        self.label.set_justify(Gtk.Justification.CENTER)
94
        self.label.show()
139
        self.label.show()
95
        self.add(self.label)
96
140
97
        self.font = Pango.FontDescription(self.options.font_desc)
141
        self.font = Pango.FontDescription(self.options.font_desc)
98
        self.update_colors()
142
        self.update_colors()
143
        self.update_mouse_enabled()
99
144
100
        self.set_size_request(0, 0)
145
        self.set_size_request(0, 0)
101
        self.set_gravity(Gdk.Gravity.CENTER)
146
        self.set_gravity(Gdk.Gravity.CENTER)
Lines 111-116 Link Here
111
        if visual is not None:
156
        if visual is not None:
112
            self.set_visual(visual)
157
            self.set_visual(visual)
113
158
159
        self.box.pack_start(self.img, expand=False, fill=True, padding=0)
160
        self.box.pack_end(self.label, expand=False, fill=True, padding=0)
161
114
        self.labelmngr = None
162
        self.labelmngr = None
115
        self.enabled = True
163
        self.enabled = True
116
        self.on_change_mode()
164
        self.on_change_mode()
Lines 177-182 Link Here
177
        self.set_active_monitor(self.monitor)
225
        self.set_active_monitor(self.monitor)
178
226
179
227
228
    def update_mouse_enabled(self):
229
        if self.options.mouse:
230
            if not self.button_pixbufs:
231
                self.button_pixbufs = load_button_pixbufs(
232
                    Gdk.color_parse(self.options.font_color)
233
                )
234
            self.img.show()
235
            self.update_image_tag = GLib.idle_add(self.update_image)
236
        else:
237
            self.img.hide()
238
            if self.update_image_tag is not None:
239
                GLib.source_remove(self.update_image_tag)
240
                self.update_image_tag = None
241
242
180
    def update_font(self):
243
    def update_font(self):
181
        _, window_height = self.get_size()
244
        _, window_height = self.get_size()
182
        text = self.label.get_text()
245
        text = self.label.get_text()
Lines 185-193 Link Here
185
        self.label.get_pango_context().set_font_description(self.font)
248
        self.label.get_pango_context().set_font_description(self.font)
186
249
187
250
251
    def update_image(self):
252
        if not self.button_pixbufs:
253
            self.update_image_tag = None
254
            return False
255
256
        pixbuf = self.button_pixbufs[0]
257
        copied = False
258
259
        for index, button_state in enumerate(self.button_states):
260
            if button_state is None:
261
                continue
262
            if button_state.pressed:
263
                alpha = 255
264
            else:
265
                if self.options.button_hide_duration > 0:
266
                    delta_time = (datetime.now() - button_state.stamp).total_seconds()
267
                    hide_time = delta_time / self.options.button_hide_duration
268
                else:
269
                    hide_time = 1
270
                if hide_time < 1:
271
                    alpha = int(255 * (1 - hide_time))
272
                else:
273
                    self.button_states[index] = None
274
                    continue
275
276
            if not copied:
277
                pixbuf = pixbuf.copy()
278
                copied = True
279
            self.button_pixbufs[button_state.btn].composite(
280
                pixbuf, 0, 0, pixbuf.get_width(), pixbuf.get_height(),
281
                0, 0, 1, 1,
282
                GdkPixbuf.InterpType.NEAREST, alpha
283
            )
284
285
        _, height = self.get_size()
286
        scale = height / pixbuf.get_height()
287
        if scale != 1:
288
            width = int(pixbuf.get_width() * scale)
289
            pixbuf = pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)
290
        self.img.set_from_pixbuf(pixbuf)
291
292
        if not copied:
293
            self.update_image_tag = None
294
            return False
295
        return True
296
297
188
    def update_colors(self):
298
    def update_colors(self):
189
        self.label.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse(self.options.font_color))
299
        font_color = Gdk.color_parse(self.options.font_color)
300
        self.label.modify_fg(Gtk.StateFlags.NORMAL, font_color)
190
        self.bg_color = Gdk.color_parse(self.options.bg_color)
301
        self.bg_color = Gdk.color_parse(self.options.bg_color)
302
        if self.options.mouse and self.button_pixbufs:
303
            self.button_pixbufs = load_button_pixbufs(font_color)
191
304
192
305
193
    def on_draw(self, widget, cr):
306
    def on_draw(self, widget, cr):
Lines 215-220 Link Here
215
        self.label.set_padding(window_width // 100, 0)
328
        self.label.set_padding(window_width // 100, 0)
216
329
217
        self.update_font()
330
        self.update_font()
331
        self.update_image()
218
332
219
333
220
    def update_geometry(self, configure=False):
334
    def update_geometry(self, configure=False):
Lines 273-278 Link Here
273
        self.quit(exit_status=os.EX_SOFTWARE)
387
        self.quit(exit_status=os.EX_SOFTWARE)
274
388
275
389
390
    def timed_show(self):
391
        if not self.get_property('visible'):
392
            self.show()
393
        if self.timer_hide:
394
            self.timer_hide.cancel()
395
        if self.options.timeout > 0 and not any(b and b.pressed for b in self.button_states):
396
            self.timer_hide = Timer(self.options.timeout, self.on_timeout_main)
397
            self.timer_hide.start()
398
399
276
    def on_label_change(self, markup):
400
    def on_label_change(self, markup):
277
        if markup is None:
401
        if markup is None:
278
            self.on_labelmngr_error()
402
            self.on_labelmngr_error()
Lines 283-301 Link Here
283
        self.label.set_attributes(attr)
407
        self.label.set_attributes(attr)
284
        self.update_font()
408
        self.update_font()
285
409
286
        if not self.get_property('visible'):
410
        self.timed_show()
287
            self.show()
288
        if self.timer_hide:
289
            self.timer_hide.cancel()
290
        if self.options.timeout > 0:
291
            self.timer_hide = Timer(self.options.timeout, self.on_timeout_main)
292
            self.timer_hide.start()
293
        if self.timer_min:
411
        if self.timer_min:
294
            self.timer_min.cancel()
412
            self.timer_min.cancel()
295
        self.timer_min = Timer(self.options.recent_thr * 2, self.on_timeout_min)
413
        self.timer_min = Timer(self.options.recent_thr * 2, self.on_timeout_min)
296
        self.timer_min.start()
414
        self.timer_min.start()
297
415
298
416
417
    def on_image_change(self, button_state):
418
        self.button_states[button_state.btn] = button_state
419
        if self.options.mouse:
420
            if not self.update_image_tag:
421
                self.update_image_tag = GLib.idle_add(self.update_image)
422
            self.timed_show()
423
424
299
    def on_timeout_main(self):
425
    def on_timeout_main(self):
300
        if not self.options.persist:
426
        if not self.options.persist:
301
            self.hide()
427
            self.hide()
Lines 311-317 Link Here
311
        self.logger.debug("Restarting LabelManager.")
437
        self.logger.debug("Restarting LabelManager.")
312
        if self.labelmngr:
438
        if self.labelmngr:
313
            self.labelmngr.stop()
439
            self.labelmngr.stop()
314
        self.labelmngr = LabelManager(self.on_label_change, logger=self.logger,
440
        self.labelmngr = LabelManager(self.on_label_change,
441
                                      self.on_image_change,
442
                                      logger=self.logger,
315
                                      key_mode=self.options.key_mode,
443
                                      key_mode=self.options.key_mode,
316
                                      bak_mode=self.options.bak_mode,
444
                                      bak_mode=self.options.bak_mode,
317
                                      mods_mode=self.options.mods_mode,
445
                                      mods_mode=self.options.mods_mode,
Lines 494-499 Link Here
494
            self.font = widget.props.font_desc
622
            self.font = widget.props.font_desc
495
            self.update_font()
623
            self.update_font()
496
624
625
        def on_cbox_mouse_changed(widget, data=None):
626
            self.options.mouse = widget.get_active()
627
            self.logger.debug("Mouse changed: %s." % self.options.mouse)
628
            self.update_mouse_enabled()
629
630
        def on_sb_mouse_duration_changed(widget, data=None):
631
            self.options.button_hide_duration = widget.get_value()
632
            self.logger.debug("Button hide duration value changed: %f." % self.options.button_hide_duration)
633
497
        frm_time = Gtk.Frame(label_widget=Gtk.Label("<b>%s</b>" % _("Time"),
634
        frm_time = Gtk.Frame(label_widget=Gtk.Label("<b>%s</b>" % _("Time"),
498
                                                    use_markup=True),
635
                                                    use_markup=True),
499
                             border_width=4,
636
                             border_width=4,
Lines 711-716 Link Here
711
        grid_color.attach_next_to(adj_scale, lbl_opacity, RIGHT, 1, 1)
848
        grid_color.attach_next_to(adj_scale, lbl_opacity, RIGHT, 1, 1)
712
        frm_color.add(grid_color)
849
        frm_color.add(grid_color)
713
850
851
        frm_mouse = Gtk.Frame(label_widget=Gtk.Label("<b>%s</b>" % _("Mouse"),
852
                                                    use_markup=True),
853
                             border_width=4,
854
                             shadow_type=Gtk.ShadowType.NONE,
855
                             margin=6, hexpand=True)
856
        vbox_mouse = Gtk.VBox(spacing=6)
857
858
        chk_mouse = Gtk.CheckButton(_("Show Mouse"))
859
        chk_mouse.connect("toggled", on_cbox_mouse_changed)
860
        chk_mouse.set_active(self.options.mouse)
861
        vbox_mouse.pack_start(chk_mouse, expand=False, fill=True, padding=0)
862
863
        hbox_mouse = Gtk.HBox()
864
        lbl_mouse1 = Gtk.Label(_("Hide duration"))
865
        lbl_mouse2 = Gtk.Label(_("seconds"))
866
        sb_mouse = Gtk.SpinButton(digits=1)
867
        sb_mouse.set_increments(0.5, 1.0)
868
        sb_mouse.set_range(0.0, 2.0)
869
        sb_mouse.set_numeric(True)
870
        sb_mouse.set_update_policy(Gtk.SpinButtonUpdatePolicy.IF_VALID)
871
        sb_mouse.set_value(self.options.button_hide_duration)
872
        sb_mouse.connect("value-changed", on_sb_mouse_duration_changed)
873
        hbox_mouse.pack_start(lbl_mouse1, expand=False, fill=False, padding=6)
874
        hbox_mouse.pack_start(sb_mouse, expand=False, fill=False, padding=4)
875
        hbox_mouse.pack_start(lbl_mouse2, expand=False, fill=False, padding=4)
876
        vbox_mouse.pack_start(hbox_mouse, expand=False, fill=False, padding=6)
877
878
        frm_mouse.add(vbox_mouse)
879
        frm_mouse.show_all()
880
        
714
        hbox_main = Gtk.Grid(column_homogeneous=True)
881
        hbox_main = Gtk.Grid(column_homogeneous=True)
715
        vbox_main = Gtk.Grid(orientation=VERTICAL)
882
        vbox_main = Gtk.Grid(orientation=VERTICAL)
716
        vbox_main.add(frm_time)
883
        vbox_main.add(frm_time)
Lines 720-725 Link Here
720
        vbox_main = Gtk.Grid(orientation=VERTICAL)
887
        vbox_main = Gtk.Grid(orientation=VERTICAL)
721
        vbox_main.add(frm_kbd)
888
        vbox_main.add(frm_kbd)
722
        vbox_main.add(frm_color)
889
        vbox_main.add(frm_color)
890
        vbox_main.add(frm_mouse)
723
        hbox_main.add(vbox_main)
891
        hbox_main.add(vbox_main)
724
892
725
        box = prefs.get_content_area()
893
        box = prefs.get_content_area()
(-)a/images/mouse.original.svg (+167 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4
<svg
5
   xmlns:dc="http://purl.org/dc/elements/1.1/"
6
   xmlns:cc="http://creativecommons.org/ns#"
7
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
   xmlns:svg="http://www.w3.org/2000/svg"
9
   xmlns="http://www.w3.org/2000/svg"
10
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
   width="480"
13
   height="750"
14
   viewBox="0 0 126.99999 198.4375"
15
   version="1.1"
16
   id="svg8"
17
   inkscape:version="0.92.2 2405546, 2018-03-11"
18
   sodipodi:docname="mouse.svg">
19
  <defs
20
     id="defs2" />
21
  <sodipodi:namedview
22
     id="base"
23
     pagecolor="#ffffff"
24
     bordercolor="#666666"
25
     borderopacity="1.0"
26
     inkscape:pageopacity="0.0"
27
     inkscape:pageshadow="2"
28
     inkscape:zoom="0.88763946"
29
     inkscape:cx="179.03838"
30
     inkscape:cy="349.88737"
31
     inkscape:document-units="px"
32
     inkscape:current-layer="layer3"
33
     showgrid="false"
34
     units="px"
35
     inkscape:snap-others="true"
36
     showguides="true"
37
     inkscape:guide-bbox="true"
38
     inkscape:window-width="1920"
39
     inkscape:window-height="1200"
40
     inkscape:window-x="0"
41
     inkscape:window-y="0"
42
     inkscape:window-maximized="0"
43
     inkscape:object-nodes="false"
44
     inkscape:snap-nodes="true"
45
     inkscape:pagecheckerboard="true" />
46
  <metadata
47
     id="metadata5">
48
    <rdf:RDF>
49
      <cc:Work
50
         rdf:about="">
51
        <dc:format>image/svg+xml</dc:format>
52
        <dc:type
53
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
54
        <dc:title></dc:title>
55
      </cc:Work>
56
    </rdf:RDF>
57
  </metadata>
58
  <g
59
     inkscape:label="body"
60
     inkscape:groupmode="layer"
61
     id="layer1"
62
     transform="translate(0,-98.562491)"
63
     style="display:inline">
64
    <path
65
       id="rect4559"
66
       style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:5.94569254;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
67
       d="m 57.143525,140.74717 -0.0013,9.98617 c -4.619332,1.64094 -7.911862,6.03433 -7.911862,11.225 v 21.40449 c 0,6.58783 5.303559,11.89139 11.891385,11.89139 h 4.756555 c 6.587828,0 11.891386,-5.30356 11.891386,-11.89139 v -21.40449 c 0,-5.20862 -3.315345,-9.61467 -7.958982,-11.23035 l -0.03128,-9.98082 z m -3.156642,0 c -22.398612,0 -40.430706,18.0321 -40.430706,40.43071 v 61.8352 c 0,22.39862 18.032094,40.43072 40.430706,40.43072 h 19.026222 c 22.398612,0 40.430715,-18.0321 40.430715,-40.43072 v -61.8352 c 0,-22.39861 -18.032103,-40.43071 -40.430715,-40.43071 z"
68
       inkscape:connector-curvature="0"
69
       sodipodi:nodetypes="ccssssssccccsssssscc" />
70
  </g>
71
  <g
72
     inkscape:groupmode="layer"
73
     id="layer3"
74
     inkscape:label="buttons"
75
     style="display:inline"
76
     transform="translate(0,-0.52916665)">
77
    <g
78
       inkscape:groupmode="layer"
79
       id="layer5"
80
       inkscape:label="right"
81
       style="display:inline">
82
      <path
83
         sodipodi:nodetypes="cscccsssc"
84
         inkscape:connector-curvature="0"
85
         id="path4664"
86
         d="m 80.768052,52.273886 c 14.179695,4.712542 24.351798,18.050357 24.351798,33.852357 V 109.43335 H 63.499996 v -4.97209 h 2.37874 c 10.504583,0 19.130731,-8.629183 19.130731,-19.132577 V 63.92419 c 0,-4.456035 -1.625405,-8.462768 -4.241415,-11.650304 z"
87
         style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:5.94569254;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" />
88
    </g>
89
    <g
90
       inkscape:groupmode="layer"
91
       id="layer4"
92
       inkscape:label="middle"
93
       style="display:inline">
94
      <rect
95
         style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:5.94569254;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
96
         id="rect4603"
97
         width="13.080523"
98
         height="29.72846"
99
         x="56.959732"
100
         y="59.50766"
101
         rx="4.7565541"
102
         ry="4.7565541" />
103
    </g>
104
    <g
105
       inkscape:groupmode="layer"
106
       id="layer6"
107
       inkscape:label="left"
108
       style="display:inline">
109
      <path
110
         style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:5.94569254;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill"
111
         d="M 46.23194,52.273886 C 32.052243,56.986428 21.880146,70.324243 21.880146,86.126243 v 23.307107 h 41.619849 v -4.97208 h -2.37874 c -10.504585,0 -19.130733,-8.629193 -19.130733,-19.132587 V 63.92419 c 0,-4.456035 1.625405,-8.462768 4.241418,-11.650304 z"
112
         id="rect4605"
113
         inkscape:connector-curvature="0"
114
         sodipodi:nodetypes="cscccsssc" />
115
    </g>
116
  </g>
117
  <g
118
     inkscape:groupmode="layer"
119
     id="layer2"
120
     inkscape:label="scroll"
121
     style="display:inline"
122
     transform="translate(0,-0.52916665)">
123
    <g
124
       inkscape:groupmode="layer"
125
       id="layer7"
126
       inkscape:label="up">
127
      <path
128
         id="path4588"
129
         style="display:inline;fill:none;stroke:#ffffff;stroke-width:5.94569254;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
130
         d="M 53.19098,26.297548 63.533489,15.955041 73.809009,26.230564 M 63.533489,37.577826 V 15.955041"
131
         inkscape:connector-curvature="0"
132
         sodipodi:nodetypes="ccccc" />
133
      <path
134
         sodipodi:nodetypes="ccccc"
135
         inkscape:connector-curvature="0"
136
         d="m 53.19098,113.40566 10.342509,10.3425 10.27552,-10.27552 m -10.27552,-11.34726 v 21.62278"
137
         style="display:inline;fill:none;stroke:#ffffff;stroke-width:5.94569254;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
138
         id="path4591" />
139
    </g>
140
    <g
141
       inkscape:groupmode="layer"
142
       id="layer8"
143
       inkscape:label="down" />
144
    <g
145
       inkscape:groupmode="layer"
146
       id="layer9"
147
       inkscape:label="left">
148
      <path
149
         id="path4593"
150
         style="display:inline;fill:none;stroke:#ffffff;stroke-width:5.94569254;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
151
         d="M 33.064815,64.575308 22.722307,74.917816 32.997831,85.19333 M 44.345093,74.917816 H 22.722307"
152
         inkscape:connector-curvature="0"
153
         sodipodi:nodetypes="ccccc" />
154
    </g>
155
    <g
156
       inkscape:groupmode="layer"
157
       id="layer10"
158
       inkscape:label="right">
159
      <path
160
         id="path4595"
161
         style="display:inline;fill:none;stroke:#ffffff;stroke-width:5.94569254;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
162
         d="M 93.935173,85.19333 104.27769,74.850823 94.002157,64.575308 M 82.654895,74.850823 h 21.622795"
163
         inkscape:connector-curvature="0"
164
         sodipodi:nodetypes="ccccc" />
165
    </g>
166
  </g>
167
</svg>
(-)a/images/mouse.svg (+10 lines)
Line 0 Link Here
1
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="750" viewBox="0 0 127 198.44">
2
  <path fill="none" stroke="#fff" stroke-linecap="round" stroke-width="5.95" d="M57.14 42.18v10a11.89 11.89 0 0 0-7.91 11.22v21.4c0 6.59 5.3 11.9 11.9 11.9h4.75c6.59 0 11.89-5.31 11.89-11.9V63.4c0-5.21-3.32-9.62-7.96-11.23l-.03-9.99zm-3.15 0a40.34 40.34 0 0 0-40.43 40.44v61.83a40.34 40.34 0 0 0 40.43 40.43H73a40.34 40.34 0 0 0 40.43-40.43V82.62A40.34 40.34 0 0 0 73 42.18z" paint-order="markers stroke fill"/>
3
  <path fill="#fff" d="M46.23 51.74A35.6 35.6 0 0 0 21.88 85.6v23.3H63.5v-4.97h-2.38A19.21 19.21 0 0 1 42 84.8V63.4c0-4.46 1.63-8.47 4.24-11.66z" paint-order="markers stroke fill"/>
4
  <rect width="13.08" height="29.73" x="56.96" y="59.51" fill="#fff" paint-order="markers stroke fill" rx="4.76" ry="4.76" transform="translate(0 -.53)"/>
5
  <path fill="#fff" d="M80.77 51.74a35.6 35.6 0 0 1 24.35 33.86v23.3H63.5v-4.97h2.38A19.2 19.2 0 0 0 85 84.8V63.4c0-4.46-1.63-8.47-4.24-11.66z" paint-order="markers stroke fill"/>
6
  <path fill="none" stroke="#fff" stroke-width="5.95" d="M53.2 25.77l10.33-10.34L73.81 25.7M63.53 37.05V15.43"/>
7
  <path fill="none" stroke="#fff" stroke-width="5.95" d="M53.2 112.88l10.33 10.34 10.28-10.28M63.53 101.6v21.62"/>
8
  <path fill="none" stroke="#fff" stroke-width="5.95" d="M33.06 64.05L22.72 74.39 33 84.66M44.35 74.4H22.72"/>
9
  <path fill="none" stroke="#fff" stroke-width="5.95" d="M93.94 84.66l10.34-10.34L94 64.05M82.65 74.32h21.63"/>
10
</svg>
(-)a/screenkey (-1 / +5 lines)
Lines 70-75 Link Here
70
                    help=_("Ignore the specified KeySym"))
70
                    help=_("Ignore the specified KeySym"))
71
    ap.add_argument("--compr-cnt", type=int, metavar='COUNT',
71
    ap.add_argument("--compr-cnt", type=int, metavar='COUNT',
72
                    help=_("Compress key repeats after the specified count"))
72
                    help=_("Compress key repeats after the specified count"))
73
    ap.add_argument("-M", "--mouse", action="store_true", default=None,
74
                    help=_("show the mouse buttons"))
75
    ap.add_argument("--mouse-fade", type=float, dest='button_hide_duration',
76
                    help=_("Mouse buttons fade duration in seconds"))
73
    args = ap.parse_args()
77
    args = ap.parse_args()
74
78
75
    # Set options
79
    # Set options
Lines 77-83 Link Here
77
    for arg in ['timeout', 'position', 'persist', 'font_desc', 'font_color', 'bg_color',
81
    for arg in ['timeout', 'position', 'persist', 'font_desc', 'font_color', 'bg_color',
78
                'font_size', 'geometry', 'key_mode', 'bak_mode', 'mods_mode', 'mods_only',
82
                'font_size', 'geometry', 'key_mode', 'bak_mode', 'mods_mode', 'mods_only',
79
                'multiline', 'vis_shift', 'vis_space', 'screen', 'no_systray',
83
                'multiline', 'vis_shift', 'vis_space', 'screen', 'no_systray',
80
                'opacity', 'ignore', 'compr_cnt']:
84
                'opacity', 'ignore', 'compr_cnt', 'mouse', 'button_hide_duration']:
81
        if getattr(args, arg) is not None:
85
        if getattr(args, arg) is not None:
82
            options[arg] = getattr(args, arg)
86
            options[arg] = getattr(args, arg)
83
87

Return to bug 724986