mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2026-01-22 05:55:55 +00:00
feat: add session-lock examples
This commit is contained in:
parent
a2d6dd5f9f
commit
6264cca368
16 changed files with 587 additions and 1 deletions
27
Cargo.lock
generated
27
Cargo.lock
generated
|
|
@ -3287,6 +3287,33 @@ dependencies = [
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "session-lock"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"env_logger",
|
||||||
|
"layer-shika",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "session-lock-selectors"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"env_logger",
|
||||||
|
"layer-shika",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "session-lock-standalone"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"env_logger",
|
||||||
|
"layer-shika",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ members = [
|
||||||
"examples/declarative-config",
|
"examples/declarative-config",
|
||||||
"examples/event-loop",
|
"examples/event-loop",
|
||||||
"examples/runtime-surface-config",
|
"examples/runtime-surface-config",
|
||||||
|
"examples/session-lock",
|
||||||
|
"examples/session-lock-selectors",
|
||||||
|
"examples/session-lock-standalone",
|
||||||
"examples/simple-popup",
|
"examples/simple-popup",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ cargo run -p multi-surface
|
||||||
cargo run -p declarative-config
|
cargo run -p declarative-config
|
||||||
cargo run -p runtime-surface-config
|
cargo run -p runtime-surface-config
|
||||||
cargo run -p simple-popup
|
cargo run -p simple-popup
|
||||||
|
cargo run -p session-lock
|
||||||
|
cargo run -p session-lock-standalone
|
||||||
|
|
||||||
# Or from the example directory
|
# Or from the example directory
|
||||||
cd examples/simple-bar
|
cd examples/simple-bar
|
||||||
|
|
@ -29,6 +31,8 @@ cargo run
|
||||||
4. **event-loop** - Explore event loop integration with timers and channels
|
4. **event-loop** - Explore event loop integration with timers and channels
|
||||||
5. **runtime-surface-config** - Surface configuration manipulation at runtime
|
5. **runtime-surface-config** - Surface configuration manipulation at runtime
|
||||||
6. **simple-popup** - Showing popups and content sizing
|
6. **simple-popup** - Showing popups and content sizing
|
||||||
|
7. **session-lock-standalone** - Minimal lock-only application without layer surfaces
|
||||||
|
8. **session-lock** - Lock screen with layer shell surfaces (status bar + lock)
|
||||||
|
|
||||||
## Common Patterns
|
## Common Patterns
|
||||||
|
|
||||||
|
|
|
||||||
14
examples/session-lock-selectors/Cargo.toml
Normal file
14
examples/session-lock-selectors/Cargo.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "session-lock-selectors"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
layer-shika = { path = "../.." }
|
||||||
|
env_logger = "0.11.7"
|
||||||
|
log.workspace = true
|
||||||
50
examples/session-lock-selectors/README.md
Normal file
50
examples/session-lock-selectors/README.md
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Session Lock Selectors Example
|
||||||
|
|
||||||
|
This example demonstrates using **selectors** to configure session lock surfaces with different properties per output. It shows how to set different themes or configurations for lock screens on different monitors.
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
- Creates both a layer shell surface (status bar) and session lock surfaces
|
||||||
|
- Uses `select_lock()` to apply configurations to specific lock surfaces
|
||||||
|
- Demonstrates per-output theming (dark theme on primary output)
|
||||||
|
- Shows how to handle lock/unlock callbacks with selectors
|
||||||
|
|
||||||
|
## Selector Usage
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Apply to all lock surfaces
|
||||||
|
shell.select_lock(Surface::all())
|
||||||
|
.on_callback_with_args("unlock_requested", handler);
|
||||||
|
|
||||||
|
// Apply only to primary output's lock surface
|
||||||
|
shell.select_lock(Output::Primary)
|
||||||
|
.set_property("theme", &Value::from("dark"))?;
|
||||||
|
|
||||||
|
// Apply to regular layer surface
|
||||||
|
shell.select(Surface::named("Main"))
|
||||||
|
.on_callback("lock_requested", handler);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run -p session-lock-selectors
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Flow
|
||||||
|
|
||||||
|
1. Application starts with a status bar showing a "Lock" button
|
||||||
|
2. Click the "Lock" button to activate the session lock
|
||||||
|
3. Lock screens appear on all outputs
|
||||||
|
4. Primary output's lock screen uses dark theme
|
||||||
|
5. Enter any password and click "Unlock" to deactivate
|
||||||
|
6. Application returns to normal mode with status bar
|
||||||
|
|
||||||
|
## When to Use This Pattern
|
||||||
|
|
||||||
|
Use session lock selectors when you need to:
|
||||||
|
|
||||||
|
- Configure lock screens differently per output
|
||||||
|
- Apply different themes or properties to specific monitors
|
||||||
|
- Handle callbacks consistently across all lock surfaces
|
||||||
|
- Combine layer shell surfaces with session locks
|
||||||
51
examples/session-lock-selectors/src/main.rs
Normal file
51
examples/session-lock-selectors/src/main.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
use layer_shika::prelude::*;
|
||||||
|
use layer_shika::slint_interpreter::Value;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
env_logger::builder()
|
||||||
|
.filter_level(log::LevelFilter::Info)
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let ui_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("ui/lock.slint");
|
||||||
|
|
||||||
|
let mut shell = Shell::from_file(ui_path)
|
||||||
|
.surface("Main")
|
||||||
|
.height(42)
|
||||||
|
.exclusive_zone(42)
|
||||||
|
.namespace("session-lock-selectors-example")
|
||||||
|
.build()?;
|
||||||
|
|
||||||
|
let lock = Rc::new(shell.create_session_lock("LockScreen")?);
|
||||||
|
|
||||||
|
let lock_clone = Rc::clone(&lock);
|
||||||
|
shell.select_lock(Surface::all()).on_callback_with_args(
|
||||||
|
"unlock_requested",
|
||||||
|
move |args, _ctx| {
|
||||||
|
if let Some(password) = args.first() {
|
||||||
|
log::info!("Password entered: {:?}", password);
|
||||||
|
}
|
||||||
|
lock_clone.deactivate().ok();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
shell
|
||||||
|
.select_lock(Surface::all())
|
||||||
|
.on_callback("cancel_requested", |_ctx| {});
|
||||||
|
|
||||||
|
shell
|
||||||
|
.select_lock(Output::Primary)
|
||||||
|
.set_property("theme", &Value::from(slint::SharedString::from("dark")))?;
|
||||||
|
|
||||||
|
let lock_clone = Rc::clone(&lock);
|
||||||
|
shell
|
||||||
|
.select(Surface::named("Main"))
|
||||||
|
.on_callback("lock_requested", move |_ctx| {
|
||||||
|
lock_clone.activate().ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
shell.run()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
118
examples/session-lock-selectors/ui/lock.slint
Normal file
118
examples/session-lock-selectors/ui/lock.slint
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
LineEdit,
|
||||||
|
HorizontalBox,
|
||||||
|
VerticalBox,
|
||||||
|
} from "std-widgets.slint";
|
||||||
|
|
||||||
|
export component Main inherits Window {
|
||||||
|
background: transparent;
|
||||||
|
callback lock_requested();
|
||||||
|
|
||||||
|
default-font-size: 16px;
|
||||||
|
HorizontalLayout {
|
||||||
|
alignment: center;
|
||||||
|
Button {
|
||||||
|
text: "Lock Screen";
|
||||||
|
clicked => root.lock_requested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export component LockScreen inherits Window {
|
||||||
|
out property <string> password;
|
||||||
|
in property <string> theme: "light";
|
||||||
|
property <bool> is_primary;
|
||||||
|
|
||||||
|
callback unlock_requested(string);
|
||||||
|
callback cancel_requested();
|
||||||
|
|
||||||
|
is_primary: theme == "dark" ? true : false;
|
||||||
|
background: theme == "dark" ? #1a1a1a : #f0f0f0;
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
alignment: center;
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
alignment: center;
|
||||||
|
spacing: 20px;
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Session Locked";
|
||||||
|
font-size: 32px;
|
||||||
|
color: theme == "dark" ? #ffffff : #000000;
|
||||||
|
horizontal-alignment: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
alignment: center;
|
||||||
|
|
||||||
|
if is_primary: Rectangle {
|
||||||
|
width: self.preferred-width;
|
||||||
|
height: 30px;
|
||||||
|
background: #4a90e2;
|
||||||
|
border-radius: 15px;
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
padding: 8px;
|
||||||
|
Text {
|
||||||
|
text: "Primary Monitor";
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Enter password to unlock";
|
||||||
|
color: theme == "dark" ? #cccccc : #333333;
|
||||||
|
horizontal-alignment: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
width: 300px;
|
||||||
|
spacing: 12px;
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
text: root.password;
|
||||||
|
placeholder-text: "Password";
|
||||||
|
edited => {
|
||||||
|
root.password = self.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
spacing: 12px;
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Unlock";
|
||||||
|
primary: true;
|
||||||
|
clicked => {
|
||||||
|
root.unlock_requested(root.password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Cancel";
|
||||||
|
clicked => {
|
||||||
|
root.cancel_requested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Theme: " + theme;
|
||||||
|
color: theme == "dark" ? #888888 : #666666;
|
||||||
|
font-size: 10px;
|
||||||
|
horizontal-alignment: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
examples/session-lock-standalone/Cargo.toml
Normal file
14
examples/session-lock-standalone/Cargo.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "session-lock-standalone"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
layer-shika = { path = "../.." }
|
||||||
|
env_logger = "0.11.7"
|
||||||
|
log.workspace = true
|
||||||
53
examples/session-lock-standalone/README.md
Normal file
53
examples/session-lock-standalone/README.md
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Session Lock Standalone Example
|
||||||
|
|
||||||
|
This example demonstrates creating a **standalone session lock application** without any layer shell surfaces. This is useful for dedicated lock screen applications that don't need persistent UI elements.
|
||||||
|
|
||||||
|
## Key Differences from Regular Session Lock
|
||||||
|
|
||||||
|
### Regular Session Lock (`session-lock`)
|
||||||
|
- Creates a layer shell surface (status bar, panel, etc.)
|
||||||
|
- Requires `wlr-layer-shell` protocol
|
||||||
|
- Lock is activated via button click or external trigger
|
||||||
|
- Application has persistent UI even when unlocked
|
||||||
|
|
||||||
|
### Standalone Session Lock (this example)
|
||||||
|
- **No layer shell surfaces** - minimal mode
|
||||||
|
- Does NOT require `wlr-layer-shell` protocol
|
||||||
|
- Lock activates immediately on startup
|
||||||
|
- Application exits when lock is deactivated
|
||||||
|
- Lighter weight and simpler architecture
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run --package session-lock-standalone
|
||||||
|
```
|
||||||
|
|
||||||
|
The lock screen will appear immediately on all outputs. Enter any password and click "Unlock" to deactivate and exit.
|
||||||
|
|
||||||
|
## Code Highlights
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// Build shell WITHOUT calling .surface() - this creates minimal mode
|
||||||
|
let mut shell = Shell::from_file(ui_path).build()?;
|
||||||
|
|
||||||
|
// Create and activate the session lock immediately
|
||||||
|
let lock = Rc::new(shell.create_session_lock("LockScreen")?);
|
||||||
|
lock.activate()?;
|
||||||
|
|
||||||
|
// Shell runs until lock is deactivated
|
||||||
|
shell.run()?;
|
||||||
|
```
|
||||||
|
|
||||||
|
## When to Use This Pattern
|
||||||
|
|
||||||
|
Use standalone session locks for:
|
||||||
|
- Dedicated lock screen applications
|
||||||
|
- Screen locker daemons that only show UI when locking
|
||||||
|
- Simpler lock-only tools without status bars
|
||||||
|
- Testing and development of lock screens in isolation
|
||||||
|
|
||||||
|
Use regular session locks with layer surfaces when:
|
||||||
|
- You need persistent UI (status bar, panel, dock)
|
||||||
|
- Lock is one feature among others in your application
|
||||||
|
- You want to trigger lock activation from UI elements
|
||||||
44
examples/session-lock-standalone/src/main.rs
Normal file
44
examples/session-lock-standalone/src/main.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
use layer_shika::prelude::*;
|
||||||
|
use layer_shika::slint_interpreter::Value;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
env_logger::builder()
|
||||||
|
.filter_level(log::LevelFilter::Info)
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let ui_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("ui/lock.slint");
|
||||||
|
|
||||||
|
let mut shell = Shell::from_file(ui_path).build()?;
|
||||||
|
|
||||||
|
let lock = Rc::new(shell.create_session_lock("LockScreen")?);
|
||||||
|
|
||||||
|
let lock_clone = Rc::clone(&lock);
|
||||||
|
shell.select_lock(Surface::all()).on_callback_with_args(
|
||||||
|
"unlock_requested",
|
||||||
|
move |args, _ctx| {
|
||||||
|
if let Some(password) = args.first() {
|
||||||
|
log::info!("Password entered: {:?}", password);
|
||||||
|
}
|
||||||
|
lock_clone.deactivate().ok();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
shell
|
||||||
|
.select_lock(Surface::all())
|
||||||
|
.on_callback("cancel_requested", |_ctx| {
|
||||||
|
log::info!("Cancel requested button pressed");
|
||||||
|
});
|
||||||
|
|
||||||
|
shell
|
||||||
|
.select_lock(Surface::all())
|
||||||
|
.set_property("theme", &Value::from(slint::SharedString::from("dark")))
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.activate()?;
|
||||||
|
|
||||||
|
shell.run()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
79
examples/session-lock-standalone/ui/lock.slint
Normal file
79
examples/session-lock-standalone/ui/lock.slint
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { Button, LineEdit, HorizontalBox } from "std-widgets.slint";
|
||||||
|
|
||||||
|
// Standalone session lock - no layer surface needed!
|
||||||
|
// This component is only displayed when the lock is activated.
|
||||||
|
export component LockScreen inherits Window {
|
||||||
|
in-out property <string> password;
|
||||||
|
in-out property <string> theme: "dark";
|
||||||
|
callback unlock_requested(string);
|
||||||
|
callback cancel_requested();
|
||||||
|
|
||||||
|
background: theme == "dark" ? #1a1a1a : #f0f0f0;
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
alignment: center;
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
alignment: center;
|
||||||
|
spacing: 20px;
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "🔒 Session Locked";
|
||||||
|
font-size: 32px;
|
||||||
|
color: theme == "dark" ? #ffffff : #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "This is a standalone lock screen without any layer surfaces";
|
||||||
|
font-size: 14px;
|
||||||
|
color: theme == "dark" ? #cccccc : #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Enter password to unlock";
|
||||||
|
font-size: 16px;
|
||||||
|
color: theme == "dark" ? #ffffff : #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
width: 300px;
|
||||||
|
spacing: 12px;
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
placeholder-text: "Password";
|
||||||
|
text: root.password;
|
||||||
|
edited => {
|
||||||
|
root.password = self.text;
|
||||||
|
}
|
||||||
|
accepted => {
|
||||||
|
root.unlock_requested(root.password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
spacing: 12px;
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Unlock";
|
||||||
|
primary: true;
|
||||||
|
clicked => {
|
||||||
|
root.unlock_requested(root.password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Cancel";
|
||||||
|
clicked => {
|
||||||
|
root.cancel_requested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
examples/session-lock/Cargo.toml
Normal file
14
examples/session-lock/Cargo.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "session-lock"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
layer-shika = { path = "../.." }
|
||||||
|
env_logger = "0.11.7"
|
||||||
|
log.workspace = true
|
||||||
14
examples/session-lock/README.md
Normal file
14
examples/session-lock/README.md
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# session-lock example
|
||||||
|
|
||||||
|
Demonstrates the ext-session-lock-v1 integration with a simple lock screen, activated by a bar button click.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run -p session-lock
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Requires a compositor that supports ext-session-lock-v1.
|
||||||
|
- The example unlocks when the password field is non-empty.
|
||||||
41
examples/session-lock/src/main.rs
Normal file
41
examples/session-lock/src/main.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
use layer_shika::prelude::*;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
env_logger::builder()
|
||||||
|
.filter_level(log::LevelFilter::Info)
|
||||||
|
.init();
|
||||||
|
|
||||||
|
let ui_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("ui/lock.slint");
|
||||||
|
|
||||||
|
let mut shell = Shell::from_file(ui_path)
|
||||||
|
.surface("Main")
|
||||||
|
.height(42)
|
||||||
|
.exclusive_zone(42)
|
||||||
|
.namespace("session-lock-example")
|
||||||
|
.build()?;
|
||||||
|
|
||||||
|
let lock = Rc::new(shell.create_session_lock("LockScreen")?);
|
||||||
|
|
||||||
|
let lock_clone = Rc::clone(&lock);
|
||||||
|
shell
|
||||||
|
.select_lock(Surface::named("LockScreen"))
|
||||||
|
.on_callback_with_args("unlock_requested", move |args, _ctx| {
|
||||||
|
if let Some(password) = args.first() {
|
||||||
|
log::info!("Password entered: {:?}", password);
|
||||||
|
}
|
||||||
|
lock_clone.deactivate().ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
let lock_clone = Rc::clone(&lock);
|
||||||
|
shell
|
||||||
|
.select(Surface::named("Main"))
|
||||||
|
.on_callback("lock_requested", move |_ctx| {
|
||||||
|
lock_clone.activate().ok();
|
||||||
|
});
|
||||||
|
|
||||||
|
shell.run()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
60
examples/session-lock/ui/lock.slint
Normal file
60
examples/session-lock/ui/lock.slint
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { Button, LineEdit, HorizontalBox } from "std-widgets.slint";
|
||||||
|
|
||||||
|
export component Main inherits Window {
|
||||||
|
background: transparent;
|
||||||
|
callback lock_requested();
|
||||||
|
|
||||||
|
default-font-size: 16px;
|
||||||
|
HorizontalLayout {
|
||||||
|
alignment: center;
|
||||||
|
Button {
|
||||||
|
text: "Lock";
|
||||||
|
clicked => root.lock_requested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export component LockScreen inherits Window {
|
||||||
|
in-out property <string> password;
|
||||||
|
callback unlock_requested(string);
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
alignment: center;
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
alignment: center;
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Session Locked";
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Enter a password to unlock";
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalLayout {
|
||||||
|
width: 255px;
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
text: root.password;
|
||||||
|
edited => {
|
||||||
|
root.password = self.text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Unlock";
|
||||||
|
clicked => {
|
||||||
|
root.unlock_requested(root.password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
|
import { VerticalBox, HorizontalBox } from "std-widgets.slint";
|
||||||
|
|
||||||
export component Bar inherits Window {
|
export component Bar inherits Window {
|
||||||
default-font-size: 16px;
|
//default-font-size: 16px;
|
||||||
|
|
||||||
HorizontalBox {
|
HorizontalBox {
|
||||||
// Left section
|
// Left section
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue