Skip to content

Commit 6db8ad5

Browse files
authored
Merge pull request #80 from devmobasa/configurator-preserve-unknown
Configurator - fix GNOME issue
2 parents a36dcfe + 32c6dcb commit 6db8ad5

File tree

7 files changed

+61
-27
lines changed

7 files changed

+61
-27
lines changed

config.example.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,10 @@ exit_after_capture = false
433433
# ═══════════════════════════════════════════════════════════════════════════════
434434

435435
[session]
436-
# Enable persistence per mode (default to false for clean startup)
437-
persist_transparent = false
438-
persist_whiteboard = false
439-
persist_blackboard = false
436+
# Enable persistence per mode (default to true)
437+
persist_transparent = true
438+
persist_whiteboard = true
439+
persist_blackboard = true
440440

441441
# Persist undo/redo history alongside shapes (set false to save only visible drawings)
442442
persist_history = true

configurator/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ cd configurator
1414
cargo run
1515
```
1616

17+
On GNOME Wayland, the configurator forces the `tiny-skia` renderer by default to
18+
avoid wgpu dma-buf/present mode crashes. Override with
19+
`ICED_BACKEND=wgpu wayscriber-configurator` if desired.
20+
1721
The window loads the current config, lets you tweak values across the tabbed sections, and writes changes back via `Config::save_with_backup()`.
1822

1923
### Handy actions

configurator/src/app.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,36 @@ pub fn run() -> iced::Result {
2525
settings.window.size = Size::new(960.0, 640.0);
2626
settings.window.resizable = true;
2727
settings.window.decorations = true;
28+
if std::env::var_os("ICED_BACKEND").is_none() && should_force_tiny_skia() {
29+
// GNOME Wayland + wgpu can crash on dma-buf/present mode selection; tiny-skia avoids this.
30+
// SAFETY: setting a process-local env var before initializing iced is safe here.
31+
unsafe {
32+
std::env::set_var("ICED_BACKEND", "tiny-skia");
33+
}
34+
eprintln!(
35+
"wayscriber-configurator: GNOME Wayland detected; using tiny-skia renderer (set ICED_BACKEND=wgpu to override)."
36+
);
37+
}
2838
ConfiguratorApp::run(settings)
2939
}
3040

41+
fn should_force_tiny_skia() -> bool {
42+
if std::env::var_os("WAYLAND_DISPLAY").is_none() {
43+
return false;
44+
}
45+
let current = std::env::var("XDG_CURRENT_DESKTOP").unwrap_or_default();
46+
let session = std::env::var("XDG_SESSION_DESKTOP").unwrap_or_default();
47+
let combined = format!("{current};{session}");
48+
let combined = combined.to_ascii_lowercase();
49+
combined.contains("gnome") || combined.contains("ubuntu")
50+
}
51+
3152
#[derive(Debug)]
3253
pub struct ConfiguratorApp {
3354
draft: ConfigDraft,
3455
baseline: ConfigDraft,
3556
defaults: ConfigDraft,
57+
base_config: Arc<Config>,
3658
status: StatusMessage,
3759
active_tab: TabId,
3860
active_ui_tab: UiTabId,
@@ -82,11 +104,13 @@ impl Application for ConfiguratorApp {
82104
let baseline = defaults.clone();
83105
let override_mode = defaults.ui_toolbar_layout_mode;
84106
let config_path = Config::get_config_path().ok();
107+
let base_config = Arc::new(default_config.clone());
85108

86109
let app = Self {
87110
draft: baseline.clone(),
88111
baseline,
89112
defaults,
113+
base_config,
90114
status: StatusMessage::info("Loading configuration..."),
91115
active_tab: TabId::Drawing,
92116
active_ui_tab: UiTabId::Toolbar,
@@ -123,6 +147,7 @@ impl Application for ConfiguratorApp {
123147
let draft = ConfigDraft::from_config(config.as_ref());
124148
self.draft = draft.clone();
125149
self.baseline = draft;
150+
self.base_config = config.clone();
126151
self.override_mode = self.draft.ui_toolbar_layout_mode;
127152
self.is_dirty = false;
128153
self.status = StatusMessage::success("Configuration loaded from disk.");
@@ -153,7 +178,7 @@ impl Application for ConfiguratorApp {
153178
return Command::none();
154179
}
155180

156-
match self.draft.to_config() {
181+
match self.draft.to_config(self.base_config.as_ref()) {
157182
Ok(mut config) => {
158183
config.validate_and_clamp();
159184
self.is_saving = true;
@@ -180,6 +205,7 @@ impl Application for ConfiguratorApp {
180205
self.last_backup_path = backup.clone();
181206
self.draft = draft.clone();
182207
self.baseline = draft;
208+
self.base_config = saved_config.clone();
183209
self.is_dirty = false;
184210
let mut msg = "Configuration saved successfully.".to_string();
185211
if let Some(path) = backup {

configurator/src/models/config.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,9 @@ impl ConfigDraft {
293293
}
294294
}
295295

296-
pub fn to_config(&self) -> Result<Config, Vec<FormError>> {
296+
pub fn to_config(&self, base: &Config) -> Result<Config, Vec<FormError>> {
297297
let mut errors = Vec::new();
298-
let mut config = Config::default();
298+
let mut config = base.clone();
299299

300300
match self.drawing_color.to_color_spec() {
301301
Ok(color) => config.drawing.default_color = color,
@@ -764,7 +764,9 @@ mod tests {
764764
selected_named: NamedColorOption::Custom,
765765
};
766766

767-
let errors = draft.to_config().expect_err("expected validation errors");
767+
let errors = draft
768+
.to_config(&Config::default())
769+
.expect_err("expected validation errors");
768770
let fields: Vec<&str> = errors.iter().map(|err| err.field.as_str()).collect();
769771

770772
assert!(fields.contains(&"drawing.default_thickness"));
@@ -778,7 +780,9 @@ mod tests {
778780
draft.session_storage_mode = SessionStorageModeOption::Custom;
779781
draft.session_custom_directory = " ".to_string();
780782

781-
let config = draft.to_config().expect("to_config should succeed");
783+
let config = draft
784+
.to_config(&Config::default())
785+
.expect("to_config should succeed");
782786
assert!(config.session.custom_directory.is_none());
783787
}
784788

docs/CONFIG.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,13 @@ exit_after_capture = false
437437

438438
### `[session]` - Session Persistence
439439

440-
Optional on-disk persistence for your drawings. Disabled by default so each session starts fresh.
440+
Optional on-disk persistence for your drawings. Enabled by default so sessions resume automatically.
441441

442442
```toml
443443
[session]
444-
persist_transparent = false
445-
persist_whiteboard = false
446-
persist_blackboard = false
444+
persist_transparent = true
445+
persist_whiteboard = true
446+
persist_blackboard = true
447447
persist_history = true
448448
restore_tool_state = true
449449
storage = "auto"

src/config/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ pub(super) fn primary_config_dir() -> Result<PathBuf> {
417417
/// exit = ["Escape", "Ctrl+Q"]
418418
/// undo = ["Ctrl+Z"]
419419
/// ```
420-
#[derive(Debug, Serialize, Deserialize, Default, JsonSchema)]
420+
#[derive(Debug, Clone, Serialize, Deserialize, Default, JsonSchema)]
421421
pub struct Config {
422422
/// Drawing tool defaults (color, thickness, font size)
423423
#[serde(default)]

src/config/types.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub const PRESET_SLOTS_MAX: usize = 5;
1313
///
1414
/// Controls the default appearance of drawing tools when the overlay first opens.
1515
/// Users can change these values at runtime using keybindings.
16-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
16+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
1717
pub struct DrawingConfig {
1818
/// Default pen color - either a named color (red, green, blue, yellow, orange, pink, white, black)
1919
/// or an RGB array like `[255, 0, 0]` for red
@@ -222,7 +222,7 @@ impl Default for PresetSlotsConfig {
222222
/// Arrow drawing settings.
223223
///
224224
/// Controls the appearance of arrowheads when using the arrow tool (Ctrl+Shift+Drag).
225-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
225+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
226226
pub struct ArrowConfig {
227227
/// Arrowhead length in pixels (valid range: 5.0 - 50.0)
228228
#[serde(default = "default_arrow_length")]
@@ -249,7 +249,7 @@ impl Default for ArrowConfig {
249249
}
250250

251251
/// Undo/redo playback configuration.
252-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
252+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
253253
pub struct HistoryConfig {
254254
/// Delay in milliseconds between steps when running "undo all by delay"
255255
#[serde(default = "default_undo_all_delay_ms")]
@@ -298,7 +298,7 @@ impl Default for HistoryConfig {
298298
///
299299
/// These settings control rendering performance and smoothness. Most users
300300
/// won't need to change these from their defaults.
301-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
301+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
302302
pub struct PerformanceConfig {
303303
/// Number of buffers for buffering (valid range: 2 - 4)
304304
/// - 2 = double buffering (lower memory, potential tearing)
@@ -331,7 +331,7 @@ impl Default for PerformanceConfig {
331331
/// UI display preferences.
332332
///
333333
/// Controls the visibility and positioning of on-screen UI elements.
334-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
334+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
335335
pub struct UiConfig {
336336
/// Show the status bar displaying current color, thickness, and tool
337337
#[serde(default = "default_show_status")]
@@ -394,7 +394,7 @@ impl Default for UiConfig {
394394
}
395395

396396
/// Status bar styling configuration.
397-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
397+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
398398
pub struct StatusBarStyle {
399399
/// Font size for status bar text
400400
#[serde(default = "default_status_font_size")]
@@ -430,7 +430,7 @@ impl Default for StatusBarStyle {
430430
}
431431

432432
/// Click highlight configuration for mouse press indicator.
433-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
433+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
434434
pub struct ClickHighlightConfig {
435435
/// Whether the highlight effect starts enabled
436436
#[serde(default = "default_click_highlight_enabled")]
@@ -462,7 +462,7 @@ pub struct ClickHighlightConfig {
462462
}
463463

464464
/// Context menu visibility configuration.
465-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
465+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
466466
pub struct ContextMenuUiConfig {
467467
#[serde(default = "default_context_menu_enabled")]
468468
pub enabled: bool,
@@ -491,7 +491,7 @@ impl Default for ClickHighlightConfig {
491491
}
492492

493493
/// Help overlay styling configuration.
494-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
494+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
495495
pub struct HelpOverlayStyle {
496496
/// Font size for help overlay text
497497
#[serde(default = "default_help_font_size")]
@@ -541,7 +541,7 @@ impl Default for HelpOverlayStyle {
541541
// ─────────────────────────────────────────────────────────────────────────────
542542

543543
#[cfg(tablet)]
544-
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
544+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
545545
pub struct TabletInputConfig {
546546
/// Enable tablet/stylus events at runtime (feature must be compiled in).
547547
#[serde(default = "default_tablet_enabled")]
@@ -1015,9 +1015,9 @@ pub struct SessionConfig {
10151015
impl Default for SessionConfig {
10161016
fn default() -> Self {
10171017
Self {
1018-
persist_transparent: false,
1019-
persist_whiteboard: false,
1020-
persist_blackboard: false,
1018+
persist_transparent: true,
1019+
persist_whiteboard: true,
1020+
persist_blackboard: true,
10211021
persist_history: default_persist_history(),
10221022
restore_tool_state: default_restore_tool_state(),
10231023
storage: default_session_storage_mode(),

0 commit comments

Comments
 (0)