xss-dimmer: seperate timer handling from drawing

This commit is contained in:
Vincent Bernat 2021-12-08 00:28:21 +01:00
parent 77c1503555
commit a4bd93b969

View file

@ -43,68 +43,52 @@ def on_realize(widget):
def on_draw(widget, event, options, background, start): def on_draw(widget, event, options, background, start):
def _dim(): x, y = widget.get_position()
r = cairo.Region(cairo.RectangleInt(0, 0, *widget.get_size())) wwidth, wheight = widget.get_size()
dctx = window.begin_draw_frame(r) delta = options.end_opacity - options.start_opacity
cctx = dctx.get_cairo_context() elapsed = time.monotonic() - start
dim(cctx) current = easing_functions[options.easing_function](elapsed / options.delay)
window.end_draw_frame(dctx) opacity = delta * current + options.start_opacity
cctx = event
def dim(cctx, once=False): # Background
x, y = widget.get_position() cctx.set_operator(cairo.OPERATOR_SOURCE)
wwidth, wheight = widget.get_size() if not background:
delta = options.end_opacity - options.start_opacity cctx.set_source_rgba(0, 0, 0, opacity)
elapsed = time.monotonic() - start cctx.paint()
current = easing_functions[options.easing_function](elapsed / options.delay)
opacity = delta * current + options.start_opacity
# Background
cctx.set_operator(cairo.OPERATOR_SOURCE)
if not background:
cctx.set_source_rgba(0, 0, 0, opacity)
cctx.paint()
else:
scale = widget.get_scale_factor()
bg = background.new_subpixbuf(x, y, wwidth * scale, wheight * scale)
cctx.save()
cctx.scale(1 / scale, 1 / scale)
Gdk.cairo_set_source_pixbuf(cctx, bg, 0, 0)
cctx.paint_with_alpha(opacity)
cctx.restore()
# Remaining time
if elapsed >= options.delay:
return
remaining = str(round(options.delay - elapsed))
cctx.select_font_face(
options.font, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD
)
cctx.set_font_size(wheight // 4)
_, _, twidth, theight, _, _ = cctx.text_extents(remaining)
text_position = wwidth // 2 - twidth // 2, wheight // 2 + theight // 2
cctx.move_to(*text_position)
cctx.set_source_rgba(1, 1, 1, opacity)
cctx.show_text(remaining)
cctx.move_to(*text_position)
cctx.set_source_rgba(0, 0, 0, opacity * 2)
cctx.set_line_width(4)
cctx.text_path(remaining)
cctx.stroke()
# Rearm timer
if not once:
next_step = min(options.step, options.delay - elapsed)
on_draw.timer = GLib.timeout_add(next_step * 1000, _dim)
window = widget.get_window()
dim(event)
if not hasattr(on_draw, "timer"):
# First time we are called.
dim(event)
else: else:
# Timers already running, just repaint scale = widget.get_scale_factor()
dim(event, once=True) bg = background.new_subpixbuf(x, y, wwidth * scale, wheight * scale)
cctx.save()
cctx.scale(1 / scale, 1 / scale)
Gdk.cairo_set_source_pixbuf(cctx, bg, 0, 0)
cctx.paint_with_alpha(opacity)
cctx.restore()
# Remaining time
remaining = str(round(options.delay - elapsed))
cctx.select_font_face(
options.font, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD
)
cctx.set_font_size(wheight // 4)
_, _, twidth, theight, _, _ = cctx.text_extents(remaining)
text_position = wwidth // 2 - twidth // 2, wheight // 2 + theight // 2
cctx.move_to(*text_position)
cctx.set_source_rgba(1, 1, 1, opacity)
cctx.show_text(remaining)
cctx.move_to(*text_position)
cctx.set_source_rgba(0, 0, 0, opacity * 2)
cctx.set_line_width(4)
cctx.text_path(remaining)
cctx.stroke()
def refresh(window, options, start):
window.queue_draw()
elapsed = time.monotonic() - start
if elapsed < options.delay:
next_step = min(options.step, options.delay - elapsed)
GLib.timeout_add(options.step * 1000, refresh, window, options, start)
# See: https://easings.net/ # See: https://easings.net/
easing_functions = { easing_functions = {
@ -186,6 +170,9 @@ if __name__ == "__main__":
window.show_all() window.show_all()
# Schedule refresh with window.queue_draw()
refresh(window, options, now)
# Watch for locker window # Watch for locker window
xdisplay = display.Display() xdisplay = display.Display()
root = xdisplay.screen().root root = xdisplay.screen().root