Skip to content

Commit ace3603

Browse files
authored
Merge pull request #90 from devmobasa/toolbar-drag-fix
Toolbar drag fix
2 parents 621e55a + 44d6842 commit ace3603

File tree

16 files changed

+230
-134
lines changed

16 files changed

+230
-134
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,17 @@ ls -la ~/.config/wayscriber/config.toml
493493
RUST_LOG=info wayscriber --active # watch for TOML errors
494494
```
495495

496+
### Environment variables
497+
498+
Common toggles:
499+
- `WAYSCRIBER_TOOLBAR_DRAG_PREVIEW=0` disables inline toolbar drag preview (default: on)
500+
- `WAYSCRIBER_TOOLBAR_POINTER_LOCK=1` enables pointer-lock drag path (default: off)
501+
- `WAYSCRIBER_DEBUG_TOOLBAR_DRAG=1` enables toolbar drag logging (default: off)
502+
- `WAYSCRIBER_FORCE_INLINE_TOOLBARS=1` forces inline toolbars on Wayland (default: off)
503+
- `WAYSCRIBER_NO_TRAY=1` disables the tray icon (default: tray enabled)
504+
505+
See `docs/CONFIG.md` for the full list.
506+
496507
### Performance tuning
497508

498509
```toml

docs/CONFIG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,19 @@ pkill wayscriber
737737
wayscriber --daemon &
738738
```
739739

740+
## Environment Variables
741+
742+
These override behavior at runtime. Bool-ish values treat anything except `0`, `false`, or `off` as true.
743+
744+
- `WAYSCRIBER_NO_TRAY=1` disables the tray icon (default: tray enabled)
745+
- `WAYSCRIBER_RESUME_SESSION=1/0` forces session persistence on/off for the current run (default: unset; follows config)
746+
- `WAYSCRIBER_FORCE_INLINE_TOOLBARS=1` forces inline toolbars on Wayland (default: off)
747+
- `WAYSCRIBER_TOOLBAR_DRAG_PREVIEW=0` disables inline toolbar drag preview (default: on)
748+
- `WAYSCRIBER_TOOLBAR_POINTER_LOCK=1` enables pointer-lock drag path (experimental; default: off)
749+
- `WAYSCRIBER_DEBUG_TOOLBAR_DRAG=1` enables toolbar drag logging (default: off)
750+
- `WAYSCRIBER_DEBUG_DAMAGE=1` enables damage region logging (default: off)
751+
- `RUST_LOG=info` enables Rust logging (default: unset; use `wayscriber=debug` for app-level logs)
752+
740753
## Troubleshooting
741754

742755
### Config File Not Loading

src/backend/wayland/state.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use anyhow::{Context, Result};
44
use log::{debug, info, warn};
55
use smithay_client_toolkit::seat::pointer::CursorIcon;
6-
use smithay_client_toolkit::shell::WaylandSurface;
76
use smithay_client_toolkit::{
87
activation::{ActivationHandler, ActivationState, RequestData},
98
compositor::CompositorState,
@@ -52,7 +51,6 @@ use crate::{
5251
},
5352
config::{Action, ColorSpec, Config},
5453
input::{BoardMode, DrawingState, EraserMode, InputState, Tool, ZoomAction},
55-
notification,
5654
session::SessionOptions,
5755
ui::toolbar::{ToolbarBindingHints, ToolbarEvent, ToolbarSnapshot},
5856
};
@@ -92,6 +90,7 @@ type ScreencopyManager = wayland_protocols_wlr::screencopy::v1::client::zwlr_scr
9290
pub(super) use helpers::{
9391
damage_summary, debug_damage_logging_enabled, debug_toolbar_drag_logging_enabled, drag_log,
9492
force_inline_toolbars_requested, resolve_damage_regions, scale_damage_regions, surface_id,
93+
toolbar_drag_preview_enabled, toolbar_pointer_lock_enabled,
9594
};
9695

9796
pub(in crate::backend::wayland) struct WaylandGlobals {

src/backend/wayland/state/data.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ pub struct StateData {
3535
pub(super) last_activation_serial: Option<u32>,
3636
pub(super) pointer_over_toolbar: bool,
3737
pub(super) toolbar_dragging: bool,
38+
pub(super) toolbar_drag_preview: bool,
3839
pub(super) current_keyboard_interactivity:
3940
Option<smithay_client_toolkit::shell::wlr_layer::KeyboardInteractivity>,
4041
pub(super) toolbar_needs_recreate: bool,
4142
pub(super) toolbar_layer_shell_missing_logged: bool,
42-
pub(super) toolbar_layer_shell_notice_sent: bool,
4343
pub(super) inline_toolbars: bool,
4444
pub(super) inline_top_hits: Vec<HitRegion>,
4545
pub(super) inline_side_hits: Vec<HitRegion>,
@@ -82,10 +82,10 @@ impl StateData {
8282
last_activation_serial: None,
8383
pointer_over_toolbar: false,
8484
toolbar_dragging: false,
85+
toolbar_drag_preview: false,
8586
current_keyboard_interactivity: None,
8687
toolbar_needs_recreate: true,
8788
toolbar_layer_shell_missing_logged: false,
88-
toolbar_layer_shell_notice_sent: false,
8989
inline_toolbars: false,
9090
inline_top_hits: Vec::new(),
9191
inline_side_hits: Vec::new(),

src/backend/wayland/state/helpers.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,22 @@ pub(in crate::backend::wayland) fn debug_toolbar_drag_logging_enabled() -> bool
8787
})
8888
}
8989

90+
pub(in crate::backend::wayland) fn toolbar_pointer_lock_enabled() -> bool {
91+
static ENABLED: OnceLock<bool> = OnceLock::new();
92+
*ENABLED.get_or_init(|| {
93+
parse_boolish_env(&std::env::var("WAYSCRIBER_TOOLBAR_POINTER_LOCK").unwrap_or_default())
94+
})
95+
}
96+
97+
pub(in crate::backend::wayland) fn toolbar_drag_preview_enabled() -> bool {
98+
static ENABLED: OnceLock<bool> = OnceLock::new();
99+
*ENABLED.get_or_init(|| {
100+
parse_boolish_env(
101+
&std::env::var("WAYSCRIBER_TOOLBAR_DRAG_PREVIEW").unwrap_or_else(|_| "1".into()),
102+
)
103+
})
104+
}
105+
90106
pub(in crate::backend::wayland) fn drag_log(message: impl AsRef<str>) {
91107
if debug_toolbar_drag_logging_enabled() {
92108
log::info!("{}", message.as_ref());

src/backend/wayland/state/render/ui.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ impl WaylandState {
124124
self.input_state.clear_properties_panel_layout();
125125
}
126126

127-
// Inline toolbars (xdg fallback) render directly into main surface when layer-shell is unavailable.
128-
if self.toolbar.is_visible() && self.inline_toolbars_active() {
127+
// Inline toolbars (xdg fallback or drag preview) render directly into main surface.
128+
if self.toolbar.is_visible() && self.inline_toolbars_render_active() {
129129
let snapshot = self.toolbar_snapshot();
130130
if self.toolbar.update_snapshot(&snapshot) {
131131
self.toolbar.mark_dirty();

src/backend/wayland/state/toolbar/drag/clamp.rs

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -74,78 +74,83 @@ impl WaylandState {
7474
pub(in crate::backend::wayland::state::toolbar) fn apply_toolbar_offsets(
7575
&mut self,
7676
snapshot: &ToolbarSnapshot,
77-
) {
77+
) -> (bool, bool) {
7878
if self.surface.width() == 0 || self.surface.height() == 0 {
7979
drag_log(format!(
8080
"skip apply_toolbar_offsets: surface not configured (width={}, height={})",
8181
self.surface.width(),
8282
self.surface.height()
8383
));
84-
return;
84+
return (false, false);
8585
}
8686
let _ = self.clamp_toolbar_offsets(snapshot);
87-
if self.layer_shell.is_some() {
88-
let top_base_x = self.inline_top_base_x(snapshot);
89-
let (top_margin_left, top_margin_top, side_margin_top, side_margin_left) =
90-
geometry::compute_layer_margins(
91-
top_base_x,
92-
Self::TOP_BASE_MARGIN_TOP,
93-
Self::SIDE_BASE_MARGIN_LEFT,
94-
Self::SIDE_BASE_MARGIN_TOP,
95-
geometry::ToolbarOffsets {
96-
top_x: self.data.toolbar_top_offset,
97-
top_y: self.data.toolbar_top_offset_y,
98-
side_x: self.data.toolbar_side_offset_x,
99-
side_y: self.data.toolbar_side_offset,
100-
},
101-
);
102-
drag_log(format!(
103-
"apply_toolbar_offsets: top_margin_left={}, top_margin_top={}, side_margin_top={}, side_margin_left={}, offsets=({}, {})/({}, {}), scale={}, top_base_x={}",
87+
if self.layer_shell.is_none() {
88+
return (false, false);
89+
}
90+
let top_base_x = self.inline_top_base_x(snapshot);
91+
let (top_margin_left, top_margin_top, side_margin_top, side_margin_left) =
92+
geometry::compute_layer_margins(
93+
top_base_x,
94+
Self::TOP_BASE_MARGIN_TOP,
95+
Self::SIDE_BASE_MARGIN_LEFT,
96+
Self::SIDE_BASE_MARGIN_TOP,
97+
geometry::ToolbarOffsets {
98+
top_x: self.data.toolbar_top_offset,
99+
top_y: self.data.toolbar_top_offset_y,
100+
side_x: self.data.toolbar_side_offset_x,
101+
side_y: self.data.toolbar_side_offset,
102+
},
103+
);
104+
drag_log(format!(
105+
"apply_toolbar_offsets: top_margin_left={}, top_margin_top={}, side_margin_top={}, side_margin_left={}, offsets=({}, {})/({}, {}), scale={}, top_base_x={}",
106+
top_margin_left,
107+
top_margin_top,
108+
side_margin_top,
109+
side_margin_left,
110+
self.data.toolbar_top_offset,
111+
self.data.toolbar_top_offset_y,
112+
self.data.toolbar_side_offset_x,
113+
self.data.toolbar_side_offset,
114+
self.surface.scale(),
115+
top_base_x
116+
));
117+
if debug_toolbar_drag_logging_enabled() {
118+
debug!(
119+
"apply_toolbar_offsets: top_margin_left={} (last={:?}), top_margin_top={} (last={:?}), side_margin_top={} (last={:?}), side_margin_left={} (last={:?}), offsets=({}, {})/({}, {}), top_base_x={}",
104120
top_margin_left,
121+
self.data.last_applied_top_margin,
105122
top_margin_top,
123+
self.data.last_applied_top_margin_top,
106124
side_margin_top,
125+
self.data.last_applied_side_margin,
107126
side_margin_left,
127+
self.data.last_applied_side_margin_left,
108128
self.data.toolbar_top_offset,
109129
self.data.toolbar_top_offset_y,
110130
self.data.toolbar_side_offset_x,
111131
self.data.toolbar_side_offset,
112-
self.surface.scale(),
113132
top_base_x
114-
));
115-
if debug_toolbar_drag_logging_enabled() {
116-
debug!(
117-
"apply_toolbar_offsets: top_margin_left={} (last={:?}), top_margin_top={} (last={:?}), side_margin_top={} (last={:?}), side_margin_left={} (last={:?}), offsets=({}, {})/({}, {}), top_base_x={}",
118-
top_margin_left,
119-
self.data.last_applied_top_margin,
120-
top_margin_top,
121-
self.data.last_applied_top_margin_top,
122-
side_margin_top,
123-
self.data.last_applied_side_margin,
124-
side_margin_left,
125-
self.data.last_applied_side_margin_left,
126-
self.data.toolbar_top_offset,
127-
self.data.toolbar_top_offset_y,
128-
self.data.toolbar_side_offset_x,
129-
self.data.toolbar_side_offset,
130-
top_base_x
131-
);
132-
}
133-
let margins_changed = self.data.last_applied_top_margin != Some(top_margin_left)
134-
|| self.data.last_applied_top_margin_top != Some(top_margin_top)
135-
|| self.data.last_applied_side_margin != Some(side_margin_top)
136-
|| self.data.last_applied_side_margin_left != Some(side_margin_left);
137-
if !margins_changed {
138-
return;
139-
}
140-
self.data.last_applied_top_margin = Some(top_margin_left);
141-
self.data.last_applied_side_margin = Some(side_margin_top);
142-
self.data.last_applied_top_margin_top = Some(top_margin_top);
143-
self.data.last_applied_side_margin_left = Some(side_margin_left);
133+
);
134+
}
135+
let top_changed = self.data.last_applied_top_margin != Some(top_margin_left)
136+
|| self.data.last_applied_top_margin_top != Some(top_margin_top);
137+
let side_changed = self.data.last_applied_side_margin != Some(side_margin_top)
138+
|| self.data.last_applied_side_margin_left != Some(side_margin_left);
139+
if !top_changed && !side_changed {
140+
return (false, false);
141+
}
142+
self.data.last_applied_top_margin = Some(top_margin_left);
143+
self.data.last_applied_side_margin = Some(side_margin_top);
144+
self.data.last_applied_top_margin_top = Some(top_margin_top);
145+
self.data.last_applied_side_margin_left = Some(side_margin_left);
146+
if top_changed {
144147
self.toolbar
145148
.set_top_margins(top_margin_top, top_margin_left);
149+
}
150+
if side_changed {
146151
self.toolbar
147152
.set_side_margins(side_margin_top, side_margin_left);
148-
self.toolbar.mark_dirty();
149153
}
154+
(top_changed, side_changed)
150155
}
151156
}

0 commit comments

Comments
 (0)