"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Screenkey/screenkey.py" between
screenkey-1.4.tar.gz and screenkey-1.5.tar.gz

About: screenkey is a screencast recording tool to display your keys.

screenkey.py  (screenkey-1.4):screenkey.py  (screenkey-1.5)
skipping to change at line 20 skipping to change at line 20
import json import json
import os import os
import subprocess import subprocess
import numbers import numbers
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
import gi import gi
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
gi.require_version('Pango', '1.0') gi.require_version('Pango', '1.0')
from gi.repository import GLib from gi.repository import GLib, Gtk, Gdk, GdkPixbuf, Pango, GObject
from gi.repository import Gtk, Gdk, GdkPixbuf, Pango, GObject
import cairo import cairo
# Gtk shortcuts # Gtk shortcuts
END = Gtk.Align.END END = Gtk.Align.END
FILL = Gtk.Align.FILL FILL = Gtk.Align.FILL
TOP = Gtk.PositionType.TOP TOP = Gtk.PositionType.TOP
BOTTOM = Gtk.PositionType.BOTTOM BOTTOM = Gtk.PositionType.BOTTOM
RIGHT = Gtk.PositionType.RIGHT RIGHT = Gtk.PositionType.RIGHT
skipping to change at line 87 skipping to change at line 84
try: try:
gi.require_version(module, version) gi.require_version(module, version)
return True return True
except ValueError: except ValueError:
return False return False
class Screenkey(Gtk.Window): class Screenkey(Gtk.Window):
STATE_FILE = os.path.join(GLib.get_user_config_dir(), 'screenkey.json') STATE_FILE = os.path.join(GLib.get_user_config_dir(), 'screenkey.json')
def __init__(self, logger, options, show_settings=False): def __init__(self, logger, options, show_settings=False):
Gtk.Window.__init__(self, Gtk.WindowType.POPUP)
self.logger = logger self.logger = logger
self.logger.debug("{} {}".format(APP_NAME, VERSION)) self.logger.debug("{} {}".format(APP_NAME, VERSION))
self.exit_status = None self.exit_status = None
self.timer_hide = None self.timer_hide = None
self.timer_min = None self.timer_min = None
defaults = Options({'no_systray': False, defaults = Options({'no_systray': False,
'timeout': 2.5, 'timeout': 2.5,
'recent_thr': 0.1, 'recent_thr': 0.1,
'compr_cnt': 3, 'compr_cnt': 3,
'ignore': [], 'ignore': [],
'position': 'bottom', 'position': 'bottom',
'persist': False, 'persist': False,
'window': False,
'font_desc': 'Sans Bold', 'font_desc': 'Sans Bold',
'font_size': 'medium', 'font_size': 'medium',
'font_color': 'white', 'font_color': 'white',
'bg_color': 'black', 'bg_color': 'black',
'opacity': 0.8, 'opacity': 0.8,
'key_mode': 'composed', 'key_mode': 'composed',
'bak_mode': 'baked', 'bak_mode': 'baked',
'mods_mode': 'normal', 'mods_mode': 'normal',
'mods_only': False, 'mods_only': False,
'multiline': False, 'multiline': False,
skipping to change at line 134 skipping to change at line 130
# copy missing defaults # copy missing defaults
for k, v in defaults.items(): for k, v in defaults.items():
if k not in self.options: if k not in self.options:
self.options[k] = v self.options[k] = v
if options is not None: if options is not None:
# override with values from constructor # override with values from constructor
for k, v in options.items(): for k, v in options.items():
if v is not None: if v is not None:
self.options[k] = v self.options[k] = v
if not self.options.window:
Gtk.Window.__init__(self, Gtk.WindowType.POPUP)
self.options.persist = True
Gtk.Window.__init__(self, Gtk.WindowType.TOPLEVEL)
self.set_keep_above(True) self.set_keep_above(True)
self.set_accept_focus(False) self.set_accept_focus(False)
self.set_focus_on_map(False) self.set_focus_on_map(False)
self.set_app_paintable(True) self.set_app_paintable(True)
self.button_pixbufs = [] self.button_pixbufs = []
self.button_states = [None] * 11 self.button_states = [None] * 11
self.img = Gtk.Image() self.img = Gtk.Image()
self.update_image_tag = None self.update_image_tag = None
skipping to change at line 163 skipping to change at line 165
self.font = Pango.FontDescription(self.options.font_desc) self.font = Pango.FontDescription(self.options.font_desc)
self.update_colors() self.update_colors()
self.update_mouse_enabled() self.update_mouse_enabled()
self.set_size_request(0, 0) self.set_size_request(0, 0)
self.set_gravity(Gdk.Gravity.CENTER) self.set_gravity(Gdk.Gravity.CENTER)
self.connect("configure-event", self.on_configure) self.connect("configure-event", self.on_configure)
self.connect("draw", self.on_draw) self.connect("draw", self.on_draw)
scr = self.get_screen() scr = self.get_screen()
scr.connect("size-changed", self.on_size_changed) scr.connect("size-changed", self.on_screen_size_changed)
scr.connect("monitors-changed", self.on_monitors_changed) scr.connect("monitors-changed", self.on_monitors_changed)
self.set_active_monitor(self.options.screen) self.set_active_monitor(self.options.screen)
visual = scr.get_rgba_visual() visual = scr.get_rgba_visual()
if visual is not None: if visual is not None:
self.set_visual(visual) self.set_visual(visual)
self.box.pack_start(self.img, expand=False, fill=True, padding=0) self.box.pack_start(self.img, expand=False, fill=True, padding=0)
self.box.pack_end(self.label, expand=True, fill=True, padding=0) self.box.pack_end(self.label, expand=True, fill=True, padding=0)
skipping to change at line 221 skipping to change at line 223
# compatibility with previous versions (0.5) # compatibility with previous versions (0.5)
if options and options.key_mode == 'normal': if options and options.key_mode == 'normal':
options.key_mode = 'composed' options.key_mode = 'composed'
return options return options
def store_state(self, options): def store_state(self, options):
"""Store options""" """Store options"""
try: try:
with open(self.STATE_FILE, 'w') as f: with open(self.STATE_FILE, 'w') as f:
json.dump(options._store, f) json.dump(options._store, f, indent=4)
self.logger.debug("Options saved.") self.logger.debug("Options saved.")
except OSError: except OSError:
self.logger.debug("Cannot open %s." % self.STATE_FILE) self.logger.debug("Cannot open %s." % self.STATE_FILE)
def set_active_monitor(self, monitor): def set_active_monitor(self, monitor):
scr = self.get_screen() scr = self.get_screen()
if monitor >= scr.get_n_monitors(): if monitor >= scr.get_n_monitors():
self.monitor = 0 self.monitor = 0
else: else:
self.monitor = monitor self.monitor = monitor
self.update_geometry() self.update_geometry()
def on_monitors_changed(self, *_): def on_monitors_changed(self, monitor):
self.set_active_monitor(self.monitor) self.set_active_monitor(self.monitor)
def update_mouse_enabled(self): def update_mouse_enabled(self):
if self.options.mouse: if self.options.mouse:
if not self.button_pixbufs: if not self.button_pixbufs:
self.button_pixbufs = load_button_pixbufs( self.button_pixbufs = load_button_pixbufs(
Gdk.color_parse(self.options.font_color) Gdk.color_parse(self.options.font_color)
) )
self.img.show() self.img.show()
self.update_image_tag = GLib.idle_add(self.update_image) self.update_image_tag = GLib.idle_add(self.update_image)
skipping to change at line 322 skipping to change at line 324
def on_draw(self, widget, cr): def on_draw(self, widget, cr):
cr.set_source_rgba(self.bg_color.red_float, cr.set_source_rgba(self.bg_color.red_float,
self.bg_color.green_float, self.bg_color.green_float,
self.bg_color.blue_float, self.bg_color.blue_float,
self.options.opacity) self.options.opacity)
cr.set_operator(cairo.OPERATOR_SOURCE) cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint() cr.paint()
cr.set_operator(cairo.OPERATOR_OVER) cr.set_operator(cairo.OPERATOR_OVER)
return False return False
def on_configure(self, *_): def on_configure(self, event, data):
# set event mask for click-through # set event mask for click-through
self.input_shape_combine_region(cairo.Region(cairo.RectangleInt(0, 0, 0, 0))) self.input_shape_combine_region(cairo.Region(cairo.RectangleInt(0, 0, 0, 0)))
def on_size_changed(self): def on_screen_size_changed(self, screen):
self.width, self.height = self.get_size() self.width, self.height = self.get_size()
self.update_font() self.update_font()
self.update_image() self.update_image()
def update_geometry(self, configure=False): def update_geometry(self, configure=False):
geometry = self.get_screen().get_monitor_geometry(self.monitor) geometry = self.get_screen().get_monitor_geometry(self.monitor)
if self.options.geometry is not None: if self.options.geometry is not None:
# NOTE: this assume a single global scaling factor for all # NOTE: this assume a single global scaling factor for all
# monitors which seems to be true for GTK3: # monitors which seems to be true for GTK3:
skipping to change at line 411 skipping to change at line 413
msg.run() msg.run()
msg.destroy() msg.destroy()
self.quit(exit_status=os.EX_SOFTWARE) self.quit(exit_status=os.EX_SOFTWARE)
def timed_show(self): def timed_show(self):
if not self.get_property('visible'): if not self.get_property('visible'):
self.show() self.show()
if self.timer_hide is not None: if self.timer_hide is not None:
GObject.source_remove(self.timer_hide) GObject.source_remove(self.timer_hide)
self.timer_hide = None self.timer_hide = None
if self.options.timeout > 0 and not any(b and b.pressed for b in self.bu if self.options.timeout > 0:
tton_states): # hide automatically if mouse mode is disabled. keep the
self.timer_hide = GObject.timeout_add(self.options.timeout * 1000, s # window around otherwise as long as any of the visible keys
elf.on_timeout_main) # (mouse or modifiers) is still held
if not self.options.mouse or \
not any(b and b.pressed for b in self.button_states):
self.timer_hide = GObject.timeout_add(self.options.timeout * 100
0, self.on_timeout_main)
def on_label_change(self, markup, synthetic): def on_label_change(self, markup, synthetic):
if markup is None: if markup is None:
self.on_labelmngr_error() self.on_labelmngr_error()
return return
_, attr, text, _ = Pango.parse_markup(markup, -1, '\0') _, attr, text, _ = Pango.parse_markup(markup, -1, '\0')
self.label.set_text(text) self.label.set_text(text)
self.label.set_attributes(attr) self.label.set_attributes(attr)
self.update_font() self.update_font()
skipping to change at line 988 skipping to change at line 995
) )
about.set_website(APP_URL) about.set_website(APP_URL)
about.set_icon_name('preferences-desktop-keyboard-shortcuts') about.set_icon_name('preferences-desktop-keyboard-shortcuts')
about.set_logo_icon_name('preferences-desktop-keyboard-shortcuts') about.set_logo_icon_name('preferences-desktop-keyboard-shortcuts')
about.connect("response", lambda *_: about.hide_on_delete()) about.connect("response", lambda *_: about.hide_on_delete())
about.connect("delete-event", lambda *_: about.hide_on_delete()) about.connect("delete-event", lambda *_: about.hide_on_delete())
def on_about_dialog(self, widget, data=None): def on_about_dialog(self, widget, data=None):
self.about.show() self.about.show()
def start_lockscreen_detection(self):
from re import match
from threading import Thread
from dbus import SessionBus
from dbus.mainloop.glib import DBusGMainLoop
def filter_bus_message(bus, message):
message_member = message.get_member()
if not self.enabled or message_member != "ActiveChanged":
args_list = message.get_args_list()
if args_list[0]:
self.logger.debug("Lock Screen; Screenkey disabled.")
self.logger.debug("Unlock Screen; Screenkey enabled.")
def lockscreen_detection_loop():
session_bus = SessionBus()
signal_interface = None
for dbus_string in session_bus.list_names():
bus_name = str(dbus_string)
if match(r"org\.(\w+)\.ScreenSaver", bus_name):
signal_interface = bus_name
self.logger.debug(f"DBUS signal interface found: \"{signal_i
nterface}\" ; password should not show when unlocking the screen.")
if not signal_interface:
self.logger.debug("ScreenSaver DBUS signal interface not found;
beware: password may show when unlocking the screen!")
mainloop = GLib.MainLoop()
thread = Thread(target=lockscreen_detection_loop)
thread.daemon = True
def run(self): def run(self):
Gtk.main() Gtk.main()
return self.exit_status return self.exit_status
 End of changes. 12 change blocks. 
15 lines changed or deleted 73 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)