1
0
Fork 0

Compare commits

...

22 Commits
v0 ... master

Author SHA1 Message Date
raatty 8c8d6dfce6 Update 'Cargo.toml' 2022-10-30 11:09:54 +13:00
Raatty e3872c0a69 update lightdm-rs urls 2022-10-30 11:03:43 +13:00
Raatty 3f3bb56290 update lightdm-rs url 2021-10-21 20:55:55 +13:00
Raatty 34df640d5d theming documentation 2020-09-20 08:53:59 +12:00
Raatty e0beba1b89 styling maybe fixed 2020-09-20 08:36:19 +12:00
Raatty e29ec82802 custom styling maybe? 2020-09-16 21:52:26 +12:00
Raatty 4c7a51cacc os release thingy at bottom 2020-07-16 09:20:03 +00:00
Raatty 914e62493a seperated build and install steps in Makefile 2020-05-17 11:16:08 +12:00
Raatty c566c508ae now tested and working 2020-04-27 08:47:49 +00:00
raatty b0db4805a8 possibly unnessessary borrow muts removed 2020-04-27 13:11:34 +12:00
Raatty e49db66883 remove optimisations 2020-04-27 11:59:17 +12:00
Raatty 2999921e29 rust rewrite finished maybe? 2020-04-26 21:53:46 +12:00
Raatty 08a90cdf07 die python! 2020-04-23 21:35:00 +12:00
Raatty efd9e3de04 no more json config 2020-04-21 17:51:00 +12:00
Raatty 358968327d version 2 maybe? 2020-04-17 15:52:01 +12:00
Raatty b96074afe0 make stuffs bigger! 2020-04-15 16:06:30 +12:00
Raatty e2afd229a6 center log in button 2020-04-14 15:43:05 +12:00
Raatty 5b9a369114 setttings button visually added along with other cosmetic changes 2020-04-13 16:03:00 +12:00
Raatty 43c0b96405 stop hard coding the sed path 2020-03-26 12:06:05 +13:00
Raatty 48ff1a671e removed default text for message_label 2020-03-22 22:32:51 +13:00
Raatty 96497ff89d licence and readme 2020-03-01 17:42:12 +13:00
Raatty 2d605c85a2 version 1 maybe? 2020-03-01 17:19:59 +13:00
10 changed files with 1006 additions and 128 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

495
Cargo.lock generated Normal file
View File

@ -0,0 +1,495 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "atk"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "444daefa55f229af145ea58d77efd23725024ee1f6f3102743709aa6b18c663e"
dependencies = [
"atk-sys",
"bitflags",
"glib",
"glib-sys",
"gobject-sys",
"libc",
]
[[package]]
name = "atk-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e552c1776737a4c80110d06b36d099f47c727335f9aaa5d942a72b6863a8ec6f"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cairo-rs"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "157049ba9618aa3a61c39d5d785102c04d3b1f40632a706c621a9aedc21e6084"
dependencies = [
"bitflags",
"cairo-sys-rs",
"glib",
"glib-sys",
"gobject-sys",
"libc",
]
[[package]]
name = "cairo-sys-rs"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff65ba02cac715be836f63429ab00a767d48336efc5497c5637afb53b4f14d63"
dependencies = [
"glib-sys",
"libc",
"pkg-config",
]
[[package]]
name = "cc"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
[[package]]
name = "futures-channel"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a"
[[package]]
name = "futures-executor"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6"
[[package]]
name = "futures-macro"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-task"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27"
[[package]]
name = "futures-util"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5"
dependencies = [
"futures-core",
"futures-macro",
"futures-task",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]
[[package]]
name = "gdk"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbe5e8772fc0865c52460cdd7a59d7d47700f44d9809d1dd00eecceb769a7589"
dependencies = [
"bitflags",
"cairo-rs",
"cairo-sys-rs",
"gdk-pixbuf",
"gdk-sys",
"gio",
"gio-sys",
"glib",
"glib-sys",
"gobject-sys",
"libc",
"pango",
]
[[package]]
name = "gdk-pixbuf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e248220c46b329b097d4b158d2717f8c688f16dd76d0399ace82b3e98062bdd7"
dependencies = [
"gdk-pixbuf-sys",
"gio",
"gio-sys",
"glib",
"glib-sys",
"gobject-sys",
"libc",
]
[[package]]
name = "gdk-pixbuf-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8991b060a9e9161bafd09bf4a202e6fd404f5b4dd1a08d53a1e84256fb34ab0"
dependencies = [
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
]
[[package]]
name = "gdk-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6adf679e91d1bff0c06860287f80403e7db54c2d2424dce0a470023b56c88fbb"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pango-sys",
"pkg-config",
]
[[package]]
name = "gio"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cd10f9415cce39b53f8024bf39a21f84f8157afa52da53837b102e585a296a5"
dependencies = [
"bitflags",
"futures-channel",
"futures-core",
"futures-io",
"futures-util",
"gio-sys",
"glib",
"glib-sys",
"gobject-sys",
"lazy_static",
"libc",
]
[[package]]
name = "gio-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fad225242b9eae7ec8a063bb86974aca56885014672375e5775dc0ea3533911"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
]
[[package]]
name = "glib"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40fb573a09841b6386ddf15fd4bc6655b4f5b106ca962f57ecaecde32a0061c0"
dependencies = [
"bitflags",
"futures-channel",
"futures-core",
"futures-executor",
"futures-task",
"futures-util",
"glib-sys",
"gobject-sys",
"lazy_static",
"libc",
]
[[package]]
name = "glib-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95856f3802f446c05feffa5e24859fe6a183a7cb849c8449afc35c86b1e316e2"
dependencies = [
"libc",
"pkg-config",
]
[[package]]
name = "gobject-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31d1a804f62034eccf370006ccaef3708a71c31d561fee88564abe71177553d9"
dependencies = [
"glib-sys",
"libc",
"pkg-config",
]
[[package]]
name = "gtk"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e1e8d70290239c668594002d1b174fcc7d7ef5d26670ee141490ede8facf8f"
dependencies = [
"atk",
"bitflags",
"cairo-rs",
"cairo-sys-rs",
"cc",
"gdk",
"gdk-pixbuf",
"gdk-pixbuf-sys",
"gdk-sys",
"gio",
"gio-sys",
"glib",
"glib-sys",
"gobject-sys",
"gtk-sys",
"lazy_static",
"libc",
"pango",
"pango-sys",
]
[[package]]
name = "gtk-sys"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53def660c7b48b00b510c81ef2d2fbd3c570f1527081d8d7947f471513e1a4c1"
dependencies = [
"atk-sys",
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pango-sys",
"pkg-config",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
[[package]]
name = "libhandy"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aa9f5620e4143358bcd645fe7d7d27b974ed9148cbdd490bc811813899afa07"
dependencies = [
"bitflags",
"gdk",
"gdk-sys",
"gio",
"gio-sys",
"glib",
"glib-sys",
"gobject-sys",
"gtk",
"gtk-sys",
"lazy_static",
"libc",
"libhandy-sys",
"pango",
]
[[package]]
name = "libhandy-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d707af842e918719b71af0ac6cf31d1843f6e8a4d1e9c733b998d8d482e60446"
dependencies = [
"gdk",
"gdk-sys",
"gio",
"gio-sys",
"glib-sys",
"gobject-sys",
"gtk-sys",
"libc",
"pango-sys",
"pkg-config",
]
[[package]]
name = "light-dm-sys"
version = "0.0.1"
source = "git+https://git.raatty.club/raatty/lightdm-rs.git#a3c669583bb932e2b25372048b1e9dbda1f10e11"
dependencies = [
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
]
[[package]]
name = "lightdm"
version = "0.1.0"
source = "git+https://git.raatty.club/raatty/lightdm-rs.git#a3c669583bb932e2b25372048b1e9dbda1f10e11"
dependencies = [
"gio",
"gio-sys",
"glib",
"glib-sys",
"gobject-sys",
"libc",
"light-dm-sys",
"once_cell",
]
[[package]]
name = "lightdm-mobile-greeter"
version = "0.1.0"
dependencies = [
"gdk",
"gtk",
"libhandy",
"lightdm",
]
[[package]]
name = "once_cell"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b"
[[package]]
name = "pango"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9c6b728f1be8edb5f9f981420b651d5ea30bdb9de89f1f1262d0084a020577"
dependencies = [
"bitflags",
"glib",
"glib-sys",
"gobject-sys",
"lazy_static",
"libc",
"pango-sys",
]
[[package]]
name = "pango-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b93d84907b3cf0819bff8f13598ba72843bee579d5ebc2502e4b0367b4be7d"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
]
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
[[package]]
name = "proc-macro-hack"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63"
[[package]]
name = "proc-macro-nested"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
[[package]]
name = "proc-macro2"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "syn"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"

15
Cargo.toml Normal file
View File

@ -0,0 +1,15 @@
[package]
name = "lightdm-mobile-greeter"
version = "0.1.0"
authors = ["Raatty <me@raatty.club>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libhandy = "0.5.0"
gdk = "0.12.1"
gtk = "0.8.1"
lightdm = { git = "https://git.raatty.club/raatty/lightdm-rs.git"}
[profile.release]
panic = "abort"

21
LICENCE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Raatty
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

11
Makefile Normal file
View File

@ -0,0 +1,11 @@
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
DATADIR ?= $(PREFIX)/share
CONFDIR = /etc
target/release/lightdm-mobile-greeter: src/main.rs
cargo build --release
build: target/release/lightdm-mobile-greeter
install: build
install -Dm755 target/release/lightdm-mobile-greeter -t $(DESTDIR)$(BINDIR)
install -Dm644 lightdm-mobile-greeter.desktop -t $(DESTDIR)$(DATADIR)/xgreeters

19
README.md Normal file
View File

@ -0,0 +1,19 @@
# Lightdm mobile greeter
A simple log in screen for use on touch screens, designed for use on postmarketOS but should work for others too.
## Installing
```
make install
```
## Configuring
As of version 3 I will now try to guess the user.
lightdm.conf
```
greeter-session=lightdm-mobile-greeter
user-session=<THE CHOSEN DE TO LAUNCH AFTER SUCCESSFUL LOGIN>
```
## Theming
If you have a file at `/etc/lightdm/lightdm_mobile_greeter.css` styling will be read from it falling back to the backed in styling, checkout style.css to get ideas on what to change

124
interface.ui Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<requires lib="libhandy" version="0.0"/>
<object class="GtkWindow" id="greeter_window">
<signal name="destroy" handler="on_destry"/>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<child>
<object class="GtkBox" id="container">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="prompt_label">
<property name="visible">True</property>
<property name="label">prompt label</property>
<style>
<class name="prompt" />
</style>
</object>
</child>
<child>
<object class="GtkEntry" id="pin_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_frame">False</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="visibility">False</property>
<property name="buffer">entry_buffer</property>
<property name="input_purpose">GTK_INPUT_PURPOSE_PIN</property>
<property name="xalign">0.5</property>
<property name="caps_lock_warning">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<style>
<class name="pin" />
</style>
</object>
</child>
<child>
<object class="HdyKeypad">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">fill</property>
<property name="valign">fill</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="only_digits">True</property>
<property name="show_symbols">False</property>
<property name="right_action">delete_btn</property>
<property name="left_action">settings_btn</property>
<property name="entry">pin_entry</property>
<style>
<class name="keypad"/>
</style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="label">Login</property>
<signal name="clicked" handler="login_cb"/>
<style>
<class name="login_btn"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel" id="message_label">
<property name="visible">True</property>
<property name="label"></property>
<style>
<class name="msg"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<object class="GtkEntryBuffer" id="entry_buffer" />
<object class="GtkButton" id="delete_btn">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus-on-click">False</property>
<signal name="clicked" handler="backspace"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">edit-clear-symbolic</property>
<property name="icon_size">6</property>
</object>
</child>
</object>
<object class="GtkButton" id="settings_btn">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus-on-click">False</property>
<signal name="clicked" handler="de_popover"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">applications-system-symbolic</property>
<property name="icon_size">6</property>
</object>
</child>
</object>
<object class="GtkPopover" id="de_select">
<property name="relative_to">settings_btn</property>
<property name="position">GTK_POS_RIGHT</property>
</object>
</interface>

View File

@ -1,128 +0,0 @@
#!/usr/bin/python3
import gi
gi.require_version("Gtk", "3.0")
gi.require_version("Handy", "0.0")
#gi.require_version("LightDM", 0.0)
from gi.repository import Gtk, Handy, LightDM, Gdk
# main window
window = Gtk.Window()
window.connect("destroy", Gtk.main_quit)
display = Gdk.Display.get_default()
monitor = display.get_monitor(0)
screen_size = monitor.get_geometry()
window.set_size_request(screen_size.width, screen_size.height)
# window.set_resizable(False)
# scrollable view
scroll = Gtk.ScrolledWindow(visible=True)
window.add(scroll)
viewport = Gtk.Viewport(visible=True)
scroll.add(viewport)
# collomn box
container = Gtk.Box(
visible=True,
can_focus=False,
orientation="vertical",
halign="center",
valign="center",
hexpand=True,
vexpand=True,
spacing=12
)
container.set_size_request(screen_size.width * 0.9, screen_size.height * 0.9)
viewport.add(container)
# entry buffer
entry_buffer = Gtk.EntryBuffer()
# backspace
def backspace(btn):
length = entry_buffer.get_length()
if length <= 0:
# theres no text left to delete
return
text = entry_buffer.get_text()
print(text)
entry_buffer.delete_text(length - 1, 1)
text2 = entry_buffer.get_text()
print(text2)
delete_btn = Gtk.Button(visible=True, can_focus=True, focus_on_click=False)
db_img = Gtk.Image(visible=True, icon_name="edit-clear-symbolic")
delete_btn.add(db_img)
delete_btn.connect("clicked", backspace)
# entry
pin_entry = Gtk.Entry(
visible=True,
can_focus=False,
has_frame=False,
margin_top=12,
margin_bottom=12,
visibility=False,
buffer=entry_buffer,
input_purpose=Gtk.InputPurpose.PIN,
xalign=0.5,
caps_lock_warning=False,
hexpand=True,
vexpand=True,
)
container.add(pin_entry)
# keypad
keypad = Handy.Keypad(
visible=True,
can_focus=False,
halign="fill",
valign="fill",
margin_top=12,
margin_bottom=12,
only_digits=True,
show_symbols=False,
right_action=delete_btn,
entry=pin_entry,
)
container.add(keypad)
# greeter
greeter = LightDM.Greeter()
def login_clicked(btn):
# greeter.authenticate("demo")
greeter.respond(pin_entry.get_text())
if greeter.get_is_authenticated():
greeter.start_session_sync(None)
# login button
login_btn = Gtk.Button(label="Login", visible=True)
login_btn.connect("clicked", login_clicked)
container.add(login_btn)
# prompt label
prompt_label = Gtk.Label(visible=True)
container.add(prompt_label)
# message label
message_label = Gtk.Label(visible=True)
container.add(message_label)
greeter.connect(
"authentication-complete",
lambda g: g.get_is_authenticated() and g.start_session_sync(None),
)
greeter.connect("show-message", lambda g, m, pt: message_label.set_text(m))
greeter.connect("show-prompt", lambda g, m, t: prompt_label.set_text(m))
greeter.connect_sync()
greeter.authenticate("demo")
window.show()
window.fullscreen()
Gtk.main()

262
src/main.rs Normal file
View File

@ -0,0 +1,262 @@
use gdk;
use gtk;
use gtk::prelude::*;
use libhandy;
use lightdm;
use lightdm::{GreeterExt, SessionExt, UserExt, UserListExt};
use std::cell::RefCell;
use std::io::prelude::*;
use std::path::*;
use std::rc::Rc;
use std::{fs, io};
fn main() {
if gtk::init().is_err() {
println!("failed to init GTK");
return;
}
libhandy::Keypad::new(true, true);
let builder = gtk::Builder::new_from_string(include_str!("../interface.ui"));
let handler = Rc::new(RefCell::new(Handler::new()));
{
let mut handler_borrowed = handler.borrow_mut();
handler_borrowed.get_objects(&builder);
handler_borrowed.set_username();
handler_borrowed.setup_greeter(handler.clone());
handler_borrowed.setup_de_select(handler.clone());
}
{
let handler_borrowed = handler.borrow();
if let Ok(os_str) = pretty_name() {
handler_borrowed
.msg_label
.as_ref()
.expect("no msg label")
.set_text(&os_str);
}
}
{
let handler_borrowed = handler.borrow();
let greeter = handler_borrowed.greeter.as_ref().expect("no greeter");
let user = handler_borrowed.user.as_ref().expect("no user");
greeter.authenticate(Some(&user)).ok();
}
let handler_builder_clone = handler.clone();
builder.connect_signals(move |_, name| {
let h_login_cb_clone = handler_builder_clone.clone();
let h_backspace_clone = handler_builder_clone.clone();
let h_de_popover_clone = handler_builder_clone.clone();
match name {
"on_destry" => Box::new(|_| {
gtk::main_quit();
None
}),
"login_cb" => Box::new(move |_| {
let handler = h_login_cb_clone.borrow();
let pin_entry = handler.pin_entry.as_ref().expect("no pin_entry");
handler
.greeter
.as_ref()
.expect("no greeter")
.respond(&pin_entry.get_text())
.ok();
pin_entry.set_text("");
None
}),
"backspace" => Box::new(move |_| {
let handler = h_backspace_clone.borrow();
let pin_entry = handler.pin_entry.as_ref().expect("no pin_entry");
let length = pin_entry.get_length();
if length <= 0 {
return None;
}
pin_entry.delete_text(length - 1, Some(1));
None
}),
"de_popover" => Box::new(move |_| {
h_de_popover_clone
.borrow()
.de_select
.as_ref()
.expect("popover not found")
.popup();
None
}),
_ => panic!("unknown signal"),
}
});
let window: gtk::Window = builder
.get_object("greeter_window")
.expect("window not found");
{
let display = gdk::Display::get_default().expect("cant get display");
let monitor = display.get_monitor(0).expect("cant get monitor");
let screen_size = monitor.get_geometry();
window.set_size_request(screen_size.width, screen_size.height);
let container: gtk::Box = builder.get_object("container").expect("cant get container");
container.set_size_request(
(screen_size.width as f32 * 0.8) as i32,
(screen_size.height as f32 * 0.8) as i32,
);
let style = gtk::CssProvider::new();
let screen = gdk::Screen::get_default().expect("cant get screen");
style
.load_from_data(include_bytes!("../style.css"))
.expect("failed to load style");
gtk::StyleContext::add_provider_for_screen(
&screen,
&style,
gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
);
let custom_conf = Path::new("/etc/lightdm/lightdm_mobile_greeter.css");
if custom_conf.exists() {
let style2 = gtk::CssProvider::new();
if let Some(path) = custom_conf.to_str() {
style2.load_from_path(path).expect("failed to load style2");
}
gtk::StyleContext::add_provider_for_screen(
&screen,
&style2,
gtk::STYLE_PROVIDER_PRIORITY_USER,
)
}
}
window.show();
gtk::main();
}
#[derive(Default)]
struct Handler {
user: Option<String>,
session: Option<String>,
greeter: Option<lightdm::Greeter>,
pin_entry: Option<gtk::EntryBuffer>,
pmpt_label: Option<gtk::Label>,
msg_label: Option<gtk::Label>,
de_select: Option<gtk::Popover>,
}
impl Handler {
fn new() -> Self {
Default::default()
}
fn get_objects(&mut self, builder: &gtk::Builder) {
self.pin_entry = builder.get_object("entry_buffer");
self.pmpt_label = builder.get_object("prompt_label");
self.msg_label = builder.get_object("message_label");
self.de_select = builder.get_object("de_select");
}
fn set_username(&mut self) {
if let Some(user_list) = lightdm::UserList::get_instance() {
if let Some(name) = user_list.get_users().first().unwrap().get_name() {
let name_str = Box::<str>::from(name);
self.user = Some(String::from(name_str));
};
}
}
fn setup_greeter(&mut self, handler: Rc<RefCell<Self>>) {
let greeter = lightdm::Greeter::new();
let handler_auth_clone = handler.clone();
greeter.connect_authentication_complete(move |greeter| {
let handler_borrowed = handler_auth_clone.borrow();
if greeter.get_is_authenticated() {
greeter
.start_session_sync(Some(&handler_borrowed.session.clone().unwrap()))
.ok();
} else {
greeter
.authenticate(Some(&handler_borrowed.user.clone().unwrap()))
.ok();
}
});
let handler_msg_clone = handler.clone();
greeter.connect_show_message(move |_, msg, _| {
handler_msg_clone
.borrow()
.msg_label
.as_ref()
.expect("no msg label")
.set_text(msg);
});
let handler_prmpt_clone = handler.clone();
greeter.connect_show_prompt(move |_, msg, _| {
handler_prmpt_clone
.borrow()
.pmpt_label
.as_ref()
.expect("no msg label")
.set_text(msg);
});
greeter.connect_to_daemon_sync().ok();
self.greeter = Some(greeter);
}
fn setup_de_select(&mut self, handler: Rc<RefCell<Self>>) {
{
let session = self
.greeter
.as_ref()
.expect("wheres the greeter at")
.get_default_session_hint()
.expect("no default session");
self.session = Some(String::from(session));
}
let vbox = gtk::BoxBuilder::new()
.orientation(gtk::Orientation::Vertical)
.visible(true)
.build();
let sessions_raw = lightdm::functions::get_sessions();
let mut sessions = sessions_raw.iter().map(|s| {
(
String::from(s.get_name().expect("no name")),
String::from(s.get_key().expect("no key")),
)
});
let (name, key) = sessions.next().expect("no session");
let first = gtk::RadioButtonBuilder::new().label(&name).build();
let mut keys = Vec::new();
let mut rbs = Vec::new();
keys.push(key);
rbs.push(first.clone());
vbox.add(&first);
for (name, key) in sessions {
let key_clone = key.clone();
let rb = gtk::RadioButton::new_with_label_from_widget(&first, &name);
keys.push(key);
rbs.push(rb.clone());
vbox.add(&rb);
if self.session.clone().expect("session not found") == key_clone {
rb.set_active(true);
}
}
let keys_iter = keys.iter();
for (rb, key) in rbs.iter().zip(keys_iter) {
let handler_clone = handler.clone();
let key_clone = key.clone();
rb.connect_toggled(move |_| {
handler_clone.borrow_mut().session = Some(key_clone.clone());
});
}
self.de_select.as_ref().expect("no de select").add(&vbox);
vbox.show_all()
}
}
fn pretty_name() -> Result<String, io::Error> {
let file = fs::File::open("/etc/os-release")?;
let contents = io::BufReader::new(file);
for line_opt in contents.lines() {
let line = line_opt?;
if line.starts_with("PRETTY_NAME=") {
if let Some(name) = line.split("=").skip(1).next() {
return Ok(name.trim_matches('"').to_string());
};
}
}
Err(io::Error::new(
io::ErrorKind::NotFound,
"I tried my best :)",
))
}

58
style.css Normal file
View File

@ -0,0 +1,58 @@
window * {
background: none;
color: greenyellow;
box-shadow: none;
text-decoration: none;
}
button {
border: none;
border-radius: 20em;
}
window {
background-color: black;
}
label {
font-weight: bold;
}
button:active {
background-color: greenyellow;
color: black;
}
button:active label {
color: black;
}
hdykeypad > button label{
font-size: 5em;
font-weight: bold;
padding: 10px;
}
.login_btn > label {
font-size: 2em;
background-clip: padding-box;
padding: 0.5em;
}
.pin, .prompt {
font-size: 2em;
}
popover {
background-color: black;
font-size: 2em;
}
popover radiobutton {
padding: 1em;
}
.msg {
font-size: 1.5em;
padding: 1em;
}