| Server IP : 107.13.46.68 / Your IP : 216.73.216.232 Web Server : Apache/2.4.58 (Ubuntu) System : Linux mariOS 6.8.0-51-generic #52-Ubuntu SMP PREEMPT_DYNAMIC Thu Dec 5 13:09:44 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /lib/linuxmint/mintinstall/ |
Upload File : |
#!/usr/bin/python3
# encoding=utf-8
# -*- coding: UTF-8 -*-
from gi.repository import GLib, Gtk, GObject, Gdk
import cairo
class ScreenshotWindow(Gtk.Window):
__gsignals__ = {
'next-image': (GObject.SignalFlags.RUN_LAST, bool, (Gtk.DirectionType,)),
}
def __init__(self, parent, multiple_screenshots):
Gtk.Window.__init__(self,
type=Gtk.WindowType.TOPLEVEL,
decorated=False,
transient_for=parent,
destroy_with_parent=True,
skip_taskbar_hint=True,
skip_pager_hint=True,
type_hint=Gdk.WindowTypeHint.UTILITY,
name="ScreenshotWindow")
self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
self.screen = Gdk.Screen.get_default()
self.visual = self.screen.get_rgba_visual()
if self.visual is not None and self.screen.is_composited():
self.set_visual(self.visual)
self.set_app_paintable(True)
self.connect("draw", self.on_draw)
self.overlay = Gtk.Overlay()
self.add(self.overlay)
self.connect("realize", self.window_realized)
self.multiple_screenshots = multiple_screenshots
self.loading_pointer = Gdk.Cursor.new_from_name(Gdk.Display.get_default(), "wait")
if multiple_screenshots:
self.normal_pointer = Gdk.Cursor.new_from_name(Gdk.Display.get_default(), "grab")
self.grabbing_pointer = Gdk.Cursor.new_from_name(Gdk.Display.get_default(), "grabbing")
else:
self.normal_pointer = None
self.grabbing_pointer = None
self.connect("button-press-event", self.on_button_press_event)
self.busy = False
self.stack = Gtk.Stack(homogeneous=False,
hhomogeneous=False,
transition_duration=500,
no_show_all=True)
self.overlay.add(self.stack)
self.swipe_handler = Gtk.GestureSwipe.new(self)
# Clicking on the spinner will send the event to the window first
self.swipe_handler.set_propagation_phase(Gtk.PropagationPhase.CAPTURE)
self.swipe_handler.connect("swipe", self.swipe_or_button_release)
self.connect("key-press-event", self.on_key_press_event)
self.connect("focus-out-event", self.on_focus_out_event)
self.scroll_handler = Gtk.EventControllerScroll.new(self, Gtk.EventControllerScrollFlags.VERTICAL)
self.scroll_handler.set_propagation_phase(Gtk.PropagationPhase.CAPTURE)
self.scroll_handler.connect("scroll", self.on_scroll_event)
self.previous_scroll_event_time = 0
self.first_image_name = None
self.last_image_name = None
if self.visual is not None:
self.show_all()
self.present()
def window_realized(self, widget, data=None):
self.window = self.get_window()
self.set_busy(True)
def set_busy(self, busy):
if busy:
self.busy = True
self.window.set_cursor(self.loading_pointer)
else:
self.busy = False
self.window.set_cursor(self.normal_pointer)
def on_button_press_event(self, window, event, data=None):
if self.busy:
return Gdk.EVENT_STOP
self.window.set_cursor(self.grabbing_pointer)
return Gdk.EVENT_PROPAGATE
def has_image(self, location):
for image in self.stack.get_children():
name = self.stack.child_get_property(image, "name")
if name == location:
return True
return False
def any_images(self):
return len(self.stack.get_children()) > 0
def add_image(self, image, location):
if image.cancellable.is_cancelled():
self.set_busy(False)
return
image.show()
self.stack.add_named(image, location)
if self.first_image_name is None:
self.first_image_name = location
else:
self.last_image_name = location
self.show_image(location)
def show_image(self, image_location):
self.stack.show()
self.set_busy(False)
self.stack.set_visible_child_name(image_location)
image = self.stack.get_visible_child()
self.resize(image.width, image.height)
if self.visual is None:
self.show_all()
self.present()
def emit_next_image(self, direction):
if self.emit("next-image", direction):
self.set_busy(True)
else:
self.set_busy(False)
def on_key_press_event(self, window, event, data=None):
keyval = event.get_keyval()[1]
if keyval in (Gdk.KEY_Left, Gdk.KEY_KP_Left):
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
direction = Gtk.DirectionType.TAB_BACKWARD
elif keyval in (Gdk.KEY_Right, Gdk.KEY_KP_Right):
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
direction = Gtk.DirectionType.TAB_FORWARD
else:
self.hide()
return Gdk.EVENT_STOP
self.emit_next_image(direction)
return Gdk.EVENT_STOP
def on_scroll_event(self, controller, xd, yd, data=None):
# Getting double events for some reason..
event_time = Gtk.get_current_event().get_time()
if event_time == self.previous_scroll_event_time or not self.multiple_screenshots:
return Gdk.EVENT_STOP
if xd < 0 or yd < 0:
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
direction = Gtk.DirectionType.TAB_BACKWARD
else:
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
direction = Gtk.DirectionType.TAB_FORWARD
self.previous_scroll_event_time = event_time
self.emit_next_image(direction)
return Gdk.EVENT_PROPAGATE
def on_focus_out_event(self, window, event, data=None):
GLib.timeout_add(200, lambda w: w.hide(), window)
return Gdk.EVENT_STOP
def swipe_or_button_release(self, handler, vx, vy):
if self.busy:
return
self.window.set_cursor(self.normal_pointer)
if vx == 0 and vy == 0:
# Need to let the other events for the swipe controller (like button-release) to fire
# before destroying the window, otherwise there are warnings when their default
# handlers run.
GLib.idle_add(self.hide)
return
if not self.multiple_screenshots:
return
if vx < 0:
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
self.emit_next_image(Gtk.DirectionType.TAB_FORWARD)
elif vx > 0:
self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
self.emit_next_image(Gtk.DirectionType.TAB_BACKWARD)
def on_draw(self, window, cr):
cr.set_source_rgba(0, 0, 0, 0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)
return Gdk.EVENT_PROPAGATE