config: make ui dragging configurable
This commit is contained in:
parent
1dd20fb87b
commit
d8ee1ac19c
19 changed files with 255 additions and 12 deletions
|
|
@ -1,5 +1,9 @@
|
|||
# Unreleased
|
||||
|
||||
- Needs jay-config release.
|
||||
- Needs jay-toml-config release.
|
||||
- Needs jay-compositor release.
|
||||
|
||||
# 1.6.0
|
||||
|
||||
- Needs jay-algorithms release.
|
||||
|
|
|
|||
|
|
@ -748,6 +748,14 @@ impl Client {
|
|||
self.send(&ClientMessage::SetFlipMargin { device, margin });
|
||||
}
|
||||
|
||||
pub fn set_ui_drag_enabled(&self, enabled: bool) {
|
||||
self.send(&ClientMessage::SetUiDragEnabled { enabled });
|
||||
}
|
||||
|
||||
pub fn set_ui_drag_threshold(&self, threshold: i32) {
|
||||
self.send(&ClientMessage::SetUiDragThreshold { threshold });
|
||||
}
|
||||
|
||||
pub fn connector_connected(&self, connector: Connector) -> bool {
|
||||
let res = self.send_with_response(&ClientMessage::ConnectorConnected { connector });
|
||||
get_response!(res, false, ConnectorConnected { connected });
|
||||
|
|
|
|||
|
|
@ -517,6 +517,12 @@ pub enum ClientMessage<'a> {
|
|||
device: DrmDevice,
|
||||
margin: Duration,
|
||||
},
|
||||
SetUiDragEnabled {
|
||||
enabled: bool,
|
||||
},
|
||||
SetUiDragThreshold {
|
||||
threshold: i32,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
|
|
|||
|
|
@ -234,3 +234,17 @@ pub fn set_idle(timeout: Option<Duration>) {
|
|||
pub fn set_explicit_sync_enabled(enabled: bool) {
|
||||
get!().set_explicit_sync_enabled(enabled);
|
||||
}
|
||||
|
||||
/// Enables or disables dragging of tiles and workspaces.
|
||||
///
|
||||
/// The default is `true`.
|
||||
pub fn set_ui_drag_enabled(enabled: bool) {
|
||||
get!().set_ui_drag_enabled(enabled);
|
||||
}
|
||||
|
||||
/// Sets the distance at which ui dragging starts.
|
||||
///
|
||||
/// The default is `10`.
|
||||
pub fn set_ui_drag_threshold(threshold: i32) {
|
||||
get!().set_ui_drag_threshold(threshold);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
# Unreleased
|
||||
|
||||
- Various bugfixes.
|
||||
- Tiles and workspaces can now be dragged with the mouse.
|
||||
|
||||
# 1.6.0 (2024-09-25)
|
||||
|
||||
- Various bugfixes.
|
||||
|
|
|
|||
|
|
@ -267,6 +267,8 @@ fn start_compositor2(
|
|||
ei_clients: EiClients::new(),
|
||||
slow_ei_clients: Default::default(),
|
||||
cpu_worker,
|
||||
ui_drag_enabled: Cell::new(true),
|
||||
ui_drag_threshold_squared: Cell::new(10),
|
||||
});
|
||||
state.tracker.register(ClientId::from_raw(0));
|
||||
create_dummy_output(&state);
|
||||
|
|
|
|||
|
|
@ -759,6 +759,16 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_ui_drag_enabled(&self, enabled: bool) {
|
||||
self.state.ui_drag_enabled.set(enabled);
|
||||
}
|
||||
|
||||
fn handle_set_ui_drag_threshold(&self, threshold: i32) {
|
||||
let threshold = threshold.max(1);
|
||||
let squared = threshold.saturating_mul(threshold);
|
||||
self.state.ui_drag_threshold_squared.set(squared);
|
||||
}
|
||||
|
||||
fn handle_set_direct_scanout_enabled(
|
||||
&self,
|
||||
device: Option<DrmDevice>,
|
||||
|
|
@ -1951,6 +1961,10 @@ impl ConfigProxyHandler {
|
|||
ClientMessage::SetFlipMargin { device, margin } => self
|
||||
.handle_set_flip_margin(device, margin)
|
||||
.wrn("set_flip_margin")?,
|
||||
ClientMessage::SetUiDragEnabled { enabled } => self.handle_set_ui_drag_enabled(enabled),
|
||||
ClientMessage::SetUiDragThreshold { threshold } => {
|
||||
self.handle_set_ui_drag_threshold(threshold)
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -776,11 +776,15 @@ impl WlSeatGlobal {
|
|||
}
|
||||
|
||||
pub fn start_tile_drag(self: &Rc<Self>, tl: &Rc<dyn ToplevelNode>) {
|
||||
self.pointer_owner.start_tile_drag(self, tl);
|
||||
if self.state.ui_drag_enabled.get() {
|
||||
self.pointer_owner.start_tile_drag(self, tl);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_workspace_drag(self: &Rc<Self>, ws: &Rc<WorkspaceNode>) {
|
||||
self.pointer_owner.start_workspace_drag(self, ws);
|
||||
if self.state.ui_drag_enabled.get() {
|
||||
self.pointer_owner.start_workspace_drag(self, ws);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cancel_dnd(self: &Rc<Self>) {
|
||||
|
|
|
|||
11
src/state.rs
11
src/state.rs
|
|
@ -218,6 +218,8 @@ pub struct State {
|
|||
pub ei_clients: EiClients,
|
||||
pub slow_ei_clients: AsyncQueue<Rc<EiClient>>,
|
||||
pub cpu_worker: Rc<CpuWorker>,
|
||||
pub ui_drag_enabled: Cell<bool>,
|
||||
pub ui_drag_threshold_squared: Cell<i32>,
|
||||
}
|
||||
|
||||
// impl Drop for State {
|
||||
|
|
@ -1240,6 +1242,15 @@ impl State {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ui_drag_threshold_reached(&self, (x1, y1): (i32, i32), (x2, y2): (i32, i32)) -> bool {
|
||||
if !self.ui_drag_enabled.get() {
|
||||
return false;
|
||||
}
|
||||
let dx = x1 - x2;
|
||||
let dy = y1 - y2;
|
||||
dx * dx + dy * dy > self.ui_drag_threshold_squared.get()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
|
|||
|
|
@ -586,10 +586,7 @@ impl ContainerNode {
|
|||
match op.kind {
|
||||
SeatOpKind::Move => {
|
||||
if let CursorType::Seat(_) = id {
|
||||
const DRAG_DIST: i32 = 10;
|
||||
let dx = x - op.x;
|
||||
let dy = y - op.y;
|
||||
if dx * dx + dy * dy > DRAG_DIST * DRAG_DIST {
|
||||
if self.state.ui_drag_threshold_reached((x, y), (op.x, op.y)) {
|
||||
let node = op.child.node.clone();
|
||||
drop(seats);
|
||||
seat.start_tile_drag(&node);
|
||||
|
|
|
|||
|
|
@ -1341,10 +1341,10 @@ impl Node for OutputNode {
|
|||
fn node_on_pointer_motion(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
self.pointer_move(PointerType::Seat(seat.id()), x, y);
|
||||
if let Some((down_x, down_y)) = self.pointer_down.get(&seat.id()) {
|
||||
const DRAG_DIST: i32 = 10;
|
||||
let dx = x.round_down() - down_x;
|
||||
let dy = y.round_down() - down_y;
|
||||
if dx * dx + dy * dy > DRAG_DIST * DRAG_DIST {
|
||||
if self
|
||||
.state
|
||||
.ui_drag_threshold_reached((x.round_down(), y.round_down()), (down_x, down_y))
|
||||
{
|
||||
let rd = self.render_data.borrow_mut();
|
||||
for title in &rd.titles {
|
||||
if down_x >= title.x1 && down_x < title.x2 {
|
||||
|
|
|
|||
|
|
@ -154,6 +154,12 @@ pub struct Status {
|
|||
pub separator: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct UiDrag {
|
||||
pub enabled: Option<bool>,
|
||||
pub threshold: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum OutputMatch {
|
||||
Any(Vec<OutputMatch>),
|
||||
|
|
@ -342,6 +348,7 @@ pub struct Config {
|
|||
pub vrr: Option<Vrr>,
|
||||
pub tearing: Option<Tearing>,
|
||||
pub libei: Libei,
|
||||
pub ui_drag: UiDrag,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ pub mod shortcuts;
|
|||
mod status;
|
||||
mod tearing;
|
||||
mod theme;
|
||||
mod ui_drag;
|
||||
mod vrr;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
|
|||
|
|
@ -25,10 +25,11 @@ use {
|
|||
status::StatusParser,
|
||||
tearing::TearingParser,
|
||||
theme::ThemeParser,
|
||||
ui_drag::UiDragParser,
|
||||
vrr::VrrParser,
|
||||
},
|
||||
spanned::SpannedErrorExt,
|
||||
Action, Config, Libei, Theme,
|
||||
Action, Config, Libei, Theme, UiDrag,
|
||||
},
|
||||
toml::{
|
||||
toml_span::{DespanExt, Span, Spanned},
|
||||
|
|
@ -112,6 +113,7 @@ impl Parser for ConfigParser<'_> {
|
|||
vrr_val,
|
||||
tearing_val,
|
||||
libei_val,
|
||||
ui_drag_val,
|
||||
),
|
||||
) = ext.extract((
|
||||
(
|
||||
|
|
@ -147,6 +149,7 @@ impl Parser for ConfigParser<'_> {
|
|||
opt(val("vrr")),
|
||||
opt(val("tearing")),
|
||||
opt(val("libei")),
|
||||
opt(val("ui-drag")),
|
||||
),
|
||||
))?;
|
||||
let mut keymap = None;
|
||||
|
|
@ -338,6 +341,15 @@ impl Parser for ConfigParser<'_> {
|
|||
}
|
||||
}
|
||||
}
|
||||
let mut ui_drag = UiDrag::default();
|
||||
if let Some(value) = ui_drag_val {
|
||||
match value.parse(&mut UiDragParser(self.0)) {
|
||||
Ok(v) => ui_drag = v,
|
||||
Err(e) => {
|
||||
log::warn!("Could not parse ui-drag setting: {}", self.0.error(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Config {
|
||||
keymap,
|
||||
repeat_rate,
|
||||
|
|
@ -365,6 +377,7 @@ impl Parser for ConfigParser<'_> {
|
|||
vrr,
|
||||
tearing,
|
||||
libei,
|
||||
ui_drag,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
49
toml-config/src/config/parsers/ui_drag.rs
Normal file
49
toml-config/src/config/parsers/ui_drag.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use {
|
||||
crate::{
|
||||
config::{
|
||||
context::Context,
|
||||
extractor::{bol, int, opt, recover, Extractor, ExtractorError},
|
||||
parser::{DataType, ParseResult, Parser, UnexpectedDataType},
|
||||
parsers::exec::ExecParserError,
|
||||
UiDrag,
|
||||
},
|
||||
toml::{
|
||||
toml_span::{DespanExt, Span, Spanned},
|
||||
toml_value::Value,
|
||||
},
|
||||
},
|
||||
indexmap::IndexMap,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum UiDragParserError {
|
||||
#[error(transparent)]
|
||||
Expected(#[from] UnexpectedDataType),
|
||||
#[error(transparent)]
|
||||
Exec(#[from] ExecParserError),
|
||||
#[error(transparent)]
|
||||
Extract(#[from] ExtractorError),
|
||||
}
|
||||
|
||||
pub struct UiDragParser<'a>(pub &'a Context<'a>);
|
||||
|
||||
impl Parser for UiDragParser<'_> {
|
||||
type Value = UiDrag;
|
||||
type Error = UiDragParserError;
|
||||
const EXPECTED: &'static [DataType] = &[DataType::Table];
|
||||
|
||||
fn parse_table(
|
||||
&mut self,
|
||||
span: Span,
|
||||
table: &IndexMap<Spanned<String>, Spanned<Value>>,
|
||||
) -> ParseResult<Self> {
|
||||
let mut ext = Extractor::new(self.0, span, table);
|
||||
let (enabled, threshold) =
|
||||
ext.extract((recover(opt(bol("enabled"))), recover(opt(int("threshold")))))?;
|
||||
Ok(UiDrag {
|
||||
enabled: enabled.despan(),
|
||||
threshold: threshold.despan().map(|v| v as i32),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ use {
|
|||
keyboard::{Keymap, ModifiedKeySym},
|
||||
logging::set_log_level,
|
||||
on_devices_enumerated, on_idle, quit, reload, set_default_workspace_capture,
|
||||
set_explicit_sync_enabled, set_idle,
|
||||
set_explicit_sync_enabled, set_idle, set_ui_drag_enabled, set_ui_drag_threshold,
|
||||
status::{set_i3bar_separator, set_status, set_status_command, unset_status_command},
|
||||
switch_to_vt,
|
||||
theme::{reset_colors, reset_font, reset_sizes, set_font},
|
||||
|
|
@ -1055,6 +1055,12 @@ fn load_config(initial_load: bool, persistent: &Rc<PersistentState>) {
|
|||
}
|
||||
}
|
||||
set_libei_socket_enabled(config.libei.enable_socket.unwrap_or(false));
|
||||
if let Some(enabled) = config.ui_drag.enabled {
|
||||
set_ui_drag_enabled(enabled);
|
||||
}
|
||||
if let Some(threshold) = config.ui_drag.threshold {
|
||||
set_ui_drag_threshold(threshold);
|
||||
}
|
||||
}
|
||||
|
||||
fn create_command(exec: &Exec) -> Command {
|
||||
|
|
|
|||
|
|
@ -589,6 +589,10 @@
|
|||
"libei": {
|
||||
"description": "Configures the libei settings.\n\n- Example:\n\n ```toml\n libei.enable-socket = true\n ```\n",
|
||||
"$ref": "#/$defs/Libei"
|
||||
},
|
||||
"ui-drag": {
|
||||
"description": "Configures the ui-drag settings.\n\n- Example:\n\n ```toml\n ui-drag = { enabled = false, threshold = 20 }\n ```\n",
|
||||
"$ref": "#/$defs/UiDrag"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
|
@ -1342,6 +1346,21 @@
|
|||
"flip-rotate-270"
|
||||
]
|
||||
},
|
||||
"UiDrag": {
|
||||
"description": "Describes ui-drag settings.\n\n- Example:\n\n ```toml\n ui-drag = { enabled = false, threshold = 20 }\n ```\n",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"description": "Enables or disables dragging of tiles and workspaces.\n\nThe default is `true`.\n"
|
||||
},
|
||||
"threshold": {
|
||||
"type": "integer",
|
||||
"description": "Sets the distance at which ui dragging starts.\n\nThe default is `10`.\n"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"Vrr": {
|
||||
"description": "Describes VRR settings.\n\n- Example:\n\n ```toml\n vrr = { mode = \"always\", cursor-hz = 90 }\n ```\n",
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -1154,6 +1154,18 @@ The table has the following fields:
|
|||
|
||||
The value of this field should be a [Libei](#types-Libei).
|
||||
|
||||
- `ui-drag` (optional):
|
||||
|
||||
Configures the ui-drag settings.
|
||||
|
||||
- Example:
|
||||
|
||||
```toml
|
||||
ui-drag = { enabled = false, threshold = 20 }
|
||||
```
|
||||
|
||||
The value of this field should be a [UiDrag](#types-UiDrag).
|
||||
|
||||
|
||||
<a name="types-Connector"></a>
|
||||
### `Connector`
|
||||
|
|
@ -2981,6 +2993,40 @@ The string should have one of the following values:
|
|||
|
||||
|
||||
|
||||
<a name="types-UiDrag"></a>
|
||||
### `UiDrag`
|
||||
|
||||
Describes ui-drag settings.
|
||||
|
||||
- Example:
|
||||
|
||||
```toml
|
||||
ui-drag = { enabled = false, threshold = 20 }
|
||||
```
|
||||
|
||||
Values of this type should be tables.
|
||||
|
||||
The table has the following fields:
|
||||
|
||||
- `enabled` (optional):
|
||||
|
||||
Enables or disables dragging of tiles and workspaces.
|
||||
|
||||
The default is `true`.
|
||||
|
||||
The value of this field should be a boolean.
|
||||
|
||||
- `threshold` (optional):
|
||||
|
||||
Sets the distance at which ui dragging starts.
|
||||
|
||||
The default is `10`.
|
||||
|
||||
The value of this field should be a number.
|
||||
|
||||
The numbers should be integers.
|
||||
|
||||
|
||||
<a name="types-Vrr"></a>
|
||||
### `Vrr`
|
||||
|
||||
|
|
|
|||
|
|
@ -2264,6 +2264,17 @@ Config:
|
|||
```toml
|
||||
libei.enable-socket = true
|
||||
```
|
||||
ui-drag:
|
||||
ref: UiDrag
|
||||
required: false
|
||||
description: |
|
||||
Configures the ui-drag settings.
|
||||
|
||||
- Example:
|
||||
|
||||
```toml
|
||||
ui-drag = { enabled = false, threshold = 20 }
|
||||
```
|
||||
|
||||
|
||||
Idle:
|
||||
|
|
@ -2588,3 +2599,31 @@ Format:
|
|||
description: ""
|
||||
- value: xbgr16161616f
|
||||
description: ""
|
||||
|
||||
|
||||
UiDrag:
|
||||
kind: table
|
||||
description: |
|
||||
Describes ui-drag settings.
|
||||
|
||||
- Example:
|
||||
|
||||
```toml
|
||||
ui-drag = { enabled = false, threshold = 20 }
|
||||
```
|
||||
fields:
|
||||
enabled:
|
||||
kind: boolean
|
||||
required: false
|
||||
description: |
|
||||
Enables or disables dragging of tiles and workspaces.
|
||||
|
||||
The default is `true`.
|
||||
threshold:
|
||||
kind: number
|
||||
integer_only: true
|
||||
required: false
|
||||
description: |
|
||||
Sets the distance at which ui dragging starts.
|
||||
|
||||
The default is `10`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue