summaryrefslogtreecommitdiffstats
path: root/LockWindow.py
blob: 3c85d2a6792fe476fff84cdf76c4a8700ddf6992 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import sys
import locale

from gi.repository import Gtk, Gdk, GObject, GLib


_ = locale.gettext


class LockWindow(Gtk.Window):
    __gsignals__ = {
        'logout': (GObject.SIGNAL_RUN_FIRST, None, ()),
        'tryUnlock': (GObject.SIGNAL_RUN_FIRST, None, (str,))
    }

    def __init__(self):
        Gtk.Window.__init__(self)

        bg = Gtk.Image.new_from_file("bg.svg")
        self.add(bg)

        self.set_decorated(False)
        self.set_skip_taskbar_hint(True)
        self.set_skip_pager_hint(True)
        self.set_keep_above(True)
        self.fullscreen()

        builder = Gtk.Builder()

        if not builder.add_from_file("unlock.ui"):
            sys.exit(1)

        self.unlockWindow = builder.get_object('unlock_window')
        self.lockLabel = builder.get_object('lock_label')
        self.promptEntry = builder.get_object('prompt_entry')
        self.messageLabel = builder.get_object('message_label')
        self.logoutButton = builder.get_object('logout_button')
        self.unlockButton = builder.get_object('unlock_button')

        self.unlockWindow.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.unlockWindow.set_transient_for(self)
        self.unlockWindow.set_modal(True)

        self.connect('delete-event', lambda w, e: True)
        self.unlockWindow.connect('delete-event', lambda w, e: True)

        self.promptEntry.connect('activate', lambda w: self._tryUnlock())
        self.logoutButton.connect('clicked', lambda w: self._logout())
        self.unlockButton.connect('clicked', lambda w: self._tryUnlock())

        self.reset(True)

        self.display = Gdk.Display.get_default()
        self.deviceManager = self.display.get_device_manager()

        self.unlockWindow.connect('map-event', self._grab_devices)

    def _logout(self):
        self.promptEntry.set_sensitive(False)
        self.unlockButton.set_sensitive(False)
        self.logoutButton.set_sensitive(False)
        GLib.idle_add(lambda: self.emit('logout'))

    def _tryUnlock(self):
        self.promptEntry.set_sensitive(False)
        self.unlockButton.set_sensitive(False)
        self.logoutButton.set_sensitive(False)
        GLib.idle_add(lambda: self.emit('tryUnlock', self.promptEntry.get_text()))

    def _update(self):
        self.promptEntry.set_sensitive(self._enablePromptEntry)
        self.logoutButton.set_sensitive(self._enableLogoutButton)
        self.unlockButton.set_sensitive(self._enableUnlockButton)

    def reset(self, resetButtons = False):
        if resetButtons:
            self._enablePromptEntry = True
            self._enableLogoutButton = False
            self._enableUnlockButton = True

        self.promptEntry.set_text('')
        self.messageLabel.set_label('')
        self._update()

        self.promptEntry.grab_focus()


    def updateLockMessage(self, username, logoutTime = None):
        if logoutTime is None:
            self.lockLabel.set_markup(_('This computer is currently locked by the user <i>{username}</i>.').format(username=GLib.markup_escape_text(username)))
            self._enableLogoutButton = False
        elif logoutTime > 0:
            self.lockLabel.set_markup(
                _('This computer is currently locked by the user <i>{username}</i>.\nThe user can be logged out in {minutes:02}:{seconds:02} minutes.').format(
                    username=GLib.markup_escape_text(username), minutes=logoutTime//60, seconds=logoutTime%60))
            self._enableLogoutButton = False
        else:
            self.lockLabel.set_markup(
                _('This computer is currently locked by the user <i>{username}</i>.\nThe user can be logged out now.').format(
                    username=GLib.markup_escape_text(username)))
            self._enableLogoutButton = True
        self._update()

    def setAuthMessage(self, message):
        self.messageLabel.set_label(message)

    def _grab_devices(self, w, e):
        for device in self.deviceManager.list_devices(Gdk.DeviceType.MASTER):
            device.grab(self.unlockWindow.get_window(), Gdk.GrabOwnership.APPLICATION, True, Gdk.EventMask.ALL_EVENTS_MASK, None, Gdk.CURRENT_TIME)

        return False

    def _ungrab_devices(self):
        for device in self.deviceManager.list_devices(Gdk.DeviceType.MASTER):
            device.ungrab(Gdk.CURRENT_TIME)

    def lock(self):
        self.show_all()
        self.unlockWindow.show_all()

        self.promptEntry.grab_focus()

    def unlock(self):
        self._ungrab_devices()

        self.unlockWindow.hide()
        self.hide()

        self.reset(True)