1#!/usr/local/bin/python3.8
2
3import gi
4gi.require_version('Gtk', '3.0')
5gi.require_version('GdkX11', '3.0')
6gi.require_version('CScreensaver', '1.0')
7
8from gi.repository import Gtk, Gdk, CScreensaver
9import signal
10import gettext
11import argparse
12import os
13import setproctitle
14
15import config
16import status
17from util import utils, settings
18
19signal.signal(signal.SIGINT, signal.SIG_DFL)
20gettext.install("cinnamon-screensaver", "/usr/local/share/locale")
21
22class Main:
23    """
24    This is the main entry point to the program, and it shows up
25    in the process list.  We do any theme preparation here as well.
26
27    We start the ScreensaverService from here.
28    """
29    def __init__(self):
30        parser = argparse.ArgumentParser(description='Cinnamon Screensaver')
31        parser.add_argument('--debug', dest='debug', action='store_true',
32                            help='Print out some extra debugging info')
33        parser.add_argument('--interactive-debug', dest='interactive', action='store_true',
34                            help='If multiple monitors are in use, only cover one monitor, and launch GtkInspector')
35        parser.add_argument('--disable-locking', dest='lock_disabled', action='store_true',
36                            help='Disable the lock screen')
37        parser.add_argument('--version', dest='version', action='store_true',
38                            help='Display the current version')
39        parser.add_argument('--no-daemon', dest='no_daemon', action='store_true',
40                            help="Deprecated: left for compatibility only - we never become a daemon")
41        args = parser.parse_args()
42
43        if settings.get_custom_screensaver() != '':
44            print("custom screensaver selected, exiting cinnamon-screensaver.")
45            quit()
46
47        if args.version:
48            print("cinnamon-screensaver %s" % (config.VERSION))
49            quit()
50
51        status.LockEnabled = not args.lock_disabled
52        status.Debug = args.debug
53        status.InteractiveDebug = args.interactive
54
55        if status.Debug:
56            print("Debug mode active")
57
58        if args.lock_disabled:
59            print("Locking disabled")
60
61        from service import ScreensaverService
62        # This is here mainly to allow the notification watcher to have a valid status.Debug value
63        import singletons
64
65        Gtk.Settings.get_default().connect("notify::gtk-theme-name", self.on_theme_changed)
66        self.do_style_overrides()
67
68        ScreensaverService()
69        Gtk.main()
70
71    def on_theme_changed(self, settings, pspec, data=None):
72        self.do_style_overrides()
73
74    def do_style_overrides(self):
75        """
76        Here we try to check for theme support in the current system's gtk theme.
77
78        We do this by retrieving a string of the current theme's final style sheet,
79        then searching for the .csstage style class.  If it's found, we return, otherwise
80        we add our own application-priority provider as a fallback.  While we have the
81        theme string, we check for a variable name we can use for the fallback experience,
82        and adjust it in our application stylesheet if necessary before adding it as a
83        provider.
84        """
85        theme_name = Gtk.Settings.get_default().get_property("gtk-theme-name")
86        provider = Gtk.CssProvider.get_named(theme_name)
87
88        css = provider.to_string()
89
90        if ".csstage" not in css:
91            print("Cinnamon Screensaver support not found in current theme - adding some...")
92
93            path = os.path.join(config.pkgdatadir, "cinnamon-screensaver.css")
94
95            f = open(path, 'r')
96            fallback_css = f.read()
97            f.close()
98
99            if "@define-color theme_selected_bg_color" in css:
100                pass
101            elif "@define-color selected_bg_color" in css:
102                print("replacing theme_selected_bg_color with selected_bg_color")
103                fallback_css = fallback_css.replace("@theme_selected_bg_color", "@selected_bg_color")
104            else:
105                print("replacing theme_selected_bg_color with Adwaita blue")
106                fallback_css = fallback_css.replace("@selected_bg_color", "#4a90d9")
107
108            fallback_prov = Gtk.CssProvider()
109
110            if fallback_prov.load_from_data(fallback_css.encode()):
111                Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default(), fallback_prov, 600)
112                Gtk.StyleContext.reset_widgets(Gdk.Screen.get_default())
113
114if __name__ == "__main__":
115    setproctitle.setproctitle('cinnamon-screensaver')
116
117    main = Main()
118