From 11eaccbdfbb06db2ba055cfaf17645683d10066f Mon Sep 17 00:00:00 2001 From: boltgolt Date: Thu, 3 Dec 2020 13:08:37 +0100 Subject: [PATCH] Cleanup --- howdy-gtk/debian/control | 2 +- howdy-gtk/src/authsticky.py | 205 +++++++++++++++++++++--------------- src/compare.py | 30 ++++-- 3 files changed, 141 insertions(+), 96 deletions(-) diff --git a/howdy-gtk/debian/control b/howdy-gtk/debian/control index e74a4fb..c192788 100644 --- a/howdy-gtk/debian/control +++ b/howdy-gtk/debian/control @@ -9,5 +9,5 @@ Vcs-Git: https://github.com/boltgolt/howdy Package: howdy-gtk Homepage: https://github.com/boltgolt/howdy Architecture: all -Depends: ${misc:Depends}, curl|wget, python3, python3-pip, python3-dev, python-gtk2, cmake +Depends: ${misc:Depends}, curl|wget, python3, python3-pip, python3-dev, python-gtk2, python-gtk2-dev, cmake Description: Optional UI package for Howdy, written in Gtk diff --git a/howdy-gtk/src/authsticky.py b/howdy-gtk/src/authsticky.py index 3f973d2..4d36059 100755 --- a/howdy-gtk/src/authsticky.py +++ b/howdy-gtk/src/authsticky.py @@ -20,108 +20,143 @@ from gi.repository import GObject as gobject windowWidth = 400 windowHeight = 100 +# Set default messages to show in the popup message = "Starting up... " subtext = "" class StickyWindow(gtk.Window): - def __init__(self): - gtk.Window.__init__(self) + def __init__(self): + """Initialize the sticky window""" + # Make the class a GTK window + gtk.Window.__init__(self) - self.set_title("Howdy Authentication UI") + # Set the title of the window + self.set_title("Howdy Authentication UI") - # Set a bunch of options to make the window stick and be on top of everything - self.stick() - self.set_gravity(gdk.Gravity.STATIC) - self.set_resizable(False) - self.set_keep_above(True) - self.set_app_paintable(True) - self.set_skip_pager_hint(True) - self.set_skip_taskbar_hint(True) - self.set_can_focus(False) - self.set_can_default(False) - self.set_focus(None) - self.set_type_hint(gdk.WindowTypeHint.NOTIFICATION) - self.set_decorated(False) + # Set a bunch of options to make the window stick and be on top of everything + self.stick() + self.set_gravity(gdk.Gravity.STATIC) + self.set_resizable(False) + self.set_keep_above(True) + self.set_app_paintable(True) + self.set_skip_pager_hint(True) + self.set_skip_taskbar_hint(True) + self.set_can_focus(False) + self.set_can_default(False) + self.set_focus(None) + self.set_type_hint(gdk.WindowTypeHint.NOTIFICATION) + self.set_decorated(False) - # Draw - self.connect("draw", self.draw) - self.connect("destroy", self.exit) - self.connect("button-press-event", self.exit) + # Listen for a window redraw + self.connect("draw", self.draw) + # Listen for a force close or click event and exit + self.connect("destroy", self.exit) + self.connect("button-press-event", self.exit) - darea = gtk.DrawingArea() - darea.set_size_request(windowWidth, windowHeight) - self.add(darea) + # Create a GDK drawing, restricts the window size + darea = gtk.DrawingArea() + darea.set_size_request(windowWidth, windowHeight) + self.add(darea) - screen = self.get_screen() - visual = screen.get_rgba_visual() - if visual and screen.is_composited(): - self.set_visual(visual) + # Get the default screen + screen = gdk.Screen.get_default() + visual = screen.get_rgba_visual() + if visual and screen.is_composited(): + self.set_visual(visual) - # TODO: handle more than 1 screen - self.move((screen.get_width() / 2) - (windowWidth / 2), 0) + # Move the window to the center top of the default window, where a webcam usually is + self.move((screen.get_width() / 2) - (windowWidth / 2), 0) - self.show_all() - self.resize(windowWidth, windowHeight) + # Show window and force a resize again + self.show_all() + self.resize(windowWidth, windowHeight) - gobject.timeout_add(100, self.test) + print("init") - gtk.main() + # Add a timeout to catch input passed from compare.py + gobject.timeout_add(100, self.catch_stdin) - def draw(self, widget, ctx): - # Change cursor to the kill icon - self.get_window().set_cursor(gdk.Cursor(gdk.CursorType.PIRATE)) - - ctx.set_source_rgba(0, 0, 0, .9) - ctx.set_operator(cairo.OPERATOR_SOURCE) - ctx.paint() - ctx.set_operator(cairo.OPERATOR_OVER) - - dir = os.path.dirname(os.path.abspath(__file__)) - - image_surface = cairo.ImageSurface.create_from_png("/usr/lib/howdy-gtk/logo.png") - ratio = float(windowHeight - 20) / float(image_surface.get_height()) - - ctx.translate(15, 10) - ctx.scale(ratio, ratio) - ctx.set_source_surface(image_surface) - ctx.paint() - - ctx.set_source_rgba(255, 255, 255, .9) - ctx.set_font_size(80) - - if subtext: - ctx.move_to(380, 145) - else: - ctx.move_to(380, 170) - - ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) - ctx.show_text(message) - - ctx.set_source_rgba(230, 230, 230, .8) - ctx.set_font_size(40) - ctx.move_to(380, 210) - ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) - ctx.show_text(subtext) - - def exit(self, widget, context): - gtk.main_quit() - - def test(self): - global message, subtext - - comm = sys.stdin.readline()[:-1] - - if comm: - if comm[0] == "M": - message = comm[2:] - if comm[0] == "S": - subtext = comm[2:] - - self.queue_draw() - gobject.timeout_add(100, self.test) + # Start GTK main loop + gtk.main() + def draw(self, widget, ctx): + """Draw the UI""" + # Change cursor to the kill icon + self.get_window().set_cursor(gdk.Cursor(gdk.CursorType.PIRATE)) + + # Draw a semi transparent background + ctx.set_source_rgba(0, 0, 0, .7) + ctx.set_operator(cairo.OPERATOR_SOURCE) + ctx.paint() + ctx.set_operator(cairo.OPERATOR_OVER) + + # Get absolute or relative logo path + path = "/usr/lib/howdy-gtk/logo.png" + if not os.access(path, os.R_OK): + path = "./logo.png" + + # Create image and calculate scale size based on image size + image_surface = cairo.ImageSurface.create_from_png(path) + ratio = float(windowHeight - 20) / float(image_surface.get_height()) + + # Position and draw the logo + ctx.translate(15, 10) + ctx.scale(ratio, ratio) + ctx.set_source_surface(image_surface) + ctx.paint() + + # Calculate main message positioning, as the text is heigher if there's a subtext + if subtext: + ctx.move_to(380, 145) + else: + ctx.move_to(380, 170) + + # Draw the main message + ctx.set_source_rgba(255, 255, 255, .9) + ctx.set_font_size(80) + ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) + ctx.show_text(message) + + # Draw the subtext if there is one + if subtext: + ctx.move_to(380, 210) + ctx.set_source_rgba(230, 230, 230, .8) + ctx.set_font_size(40) + ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) + ctx.show_text(subtext) + + + def catch_stdin(self): + """Catch input from stdin and redraw""" + global message, subtext + + # Wait for a line on stdin + comm = sys.stdin.readline()[:-1] + + # If the line is not empty + if comm: + # Parse a message + if comm[0] == "M": + message = comm[2:] + # Parse subtext + if comm[0] == "S": + subtext = comm[2:] + + # Redraw the ui + self.queue_draw() + + # Fire this function again in 10ms, as we're waiting on IO in readline anyway + gobject.timeout_add(10, self.catch_stdin) + + + def exit(self, widget, context): + """Cleanly exit""" + gtk.main_quit() + +# Make sure we quit on a SIGINT signal.signal(signal.SIGINT, signal.SIG_DFL) +# Open the GTK window window = StickyWindow() diff --git a/src/compare.py b/src/compare.py index 46d0ba1..f766bde 100644 --- a/src/compare.py +++ b/src/compare.py @@ -28,7 +28,11 @@ def exit(code): """Exit while closeing howdy-gtk properly""" global gtk_proc - gtk_proc.terminate() + # Exit the auth ui process if there is one + if 'gtk_proc' in globals(): + gtk_proc.terminate() + + # Exit compare sys.exit(code) @@ -75,15 +79,17 @@ def send_to_ui(type, message): """Send message to the auth ui""" global gtk_proc - # Format message so the ui can parse it - message = type + "=" + message + " \n" + # Only execute of the proccess started + if 'gtk_proc' in globals(): + # Format message so the ui can parse it + message = type + "=" + message + " \n" - # Try to send the message to the auth ui, but it's okay if that fails - try: - gtk_proc.stdin.write(bytearray(message.encode("ascii"))) - gtk_proc.stdin.flush() - except IOError as err: - pass + # Try to send the message to the auth ui, but it's okay if that fails + try: + gtk_proc.stdin.write(bytearray(message.encode("ascii"))) + gtk_proc.stdin.flush() + except IOError as err: + pass # Make sure we were given an username to tast against @@ -115,7 +121,11 @@ pose_predictor = None face_encoder = None # Start the auth ui -gtk_proc = subprocess.Popen(["howdy-gtk-auth"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) +try: + gtk_proc = subprocess.Popen(["python3", "-u", "../howdy-gtk/src/authsticky.py"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) +except FileNotFoundError as err: + pass + # Write to the stdin to redraw ui send_to_ui("M", "Starting up...")