aboutsummaryrefslogtreecommitdiff
path: root/src/ipc/server.rs
diff options
context:
space:
mode:
authoryrkv <yegor@tydbits.com>2025-08-16 01:42:08 -0700
committerGitHub <noreply@github.com>2025-08-16 11:42:08 +0300
commitaf30cc8df68b29973c8b9eec290f9e6b93463929 (patch)
treec216831fe217e191c958545b7536183d67b1b186 /src/ipc/server.rs
parenta003e013074b5188a2b1f2364fff90fb4caf972a (diff)
downloadniri-af30cc8df68b29973c8b9eec290f9e6b93463929.tar.gz
niri-af30cc8df68b29973c8b9eec290f9e6b93463929.tar.bz2
niri-af30cc8df68b29973c8b9eec290f9e6b93463929.zip
niri-ipc: Add window positions and sizes (#1265)
* Add window sizes and positions to the IPC * basic fixes * report window_loc instead of window pos * clean ups * make scrolling indices 1-based * add printing to niri msg windows * don't include render offset in floating tile pos --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
Diffstat (limited to 'src/ipc/server.rs')
-rw-r--r--src/ipc/server.rs33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/ipc/server.rs b/src/ipc/server.rs
index cbcf3f67..464a2a13 100644
--- a/src/ipc/server.rs
+++ b/src/ipc/server.rs
@@ -17,7 +17,8 @@ use futures_util::{select_biased, AsyncBufReadExt, AsyncWrite, AsyncWriteExt, Fu
use niri_config::OutputName;
use niri_ipc::state::{EventStreamState, EventStreamStatePart as _};
use niri_ipc::{
- Event, KeyboardLayouts, OutputConfigChanged, Overview, Reply, Request, Response, Workspace,
+ Event, KeyboardLayouts, OutputConfigChanged, Overview, Reply, Request, Response, WindowLayout,
+ Workspace,
};
use smithay::desktop::layer_map_for_output;
use smithay::input::pointer::{
@@ -477,7 +478,11 @@ async fn handle_event_stream_client(client: EventStreamClient) -> anyhow::Result
Ok(())
}
-fn make_ipc_window(mapped: &Mapped, workspace_id: Option<WorkspaceId>) -> niri_ipc::Window {
+fn make_ipc_window(
+ mapped: &Mapped,
+ workspace_id: Option<WorkspaceId>,
+ layout: WindowLayout,
+) -> niri_ipc::Window {
with_toplevel_role(mapped.toplevel(), |role| niri_ipc::Window {
id: mapped.id().get(),
title: role.title.clone(),
@@ -487,6 +492,7 @@ fn make_ipc_window(mapped: &Mapped, workspace_id: Option<WorkspaceId>) -> niri_i
is_focused: mapped.is_focused(),
is_floating: mapped.is_floating(),
is_urgent: mapped.is_urgent(),
+ layout,
})
}
@@ -657,10 +663,12 @@ impl State {
let mut events = Vec::new();
let layout = &self.niri.layout;
+ let mut batch_change_layouts: Vec<(u64, WindowLayout)> = Vec::new();
+
// Check for window changes.
let mut seen = HashSet::new();
let mut focused_id = None;
- layout.with_windows(|mapped, _, ws_id| {
+ layout.with_windows(|mapped, _, ws_id, window_layout| {
let id = mapped.id().get();
seen.insert(id);
@@ -669,7 +677,7 @@ impl State {
}
let Some(ipc_win) = state.windows.get(&id) else {
- let window = make_ipc_window(mapped, ws_id);
+ let window = make_ipc_window(mapped, ws_id, window_layout);
events.push(Event::WindowOpenedOrChanged { window });
return;
};
@@ -683,11 +691,15 @@ impl State {
});
if changed {
- let window = make_ipc_window(mapped, ws_id);
+ let window = make_ipc_window(mapped, ws_id, window_layout);
events.push(Event::WindowOpenedOrChanged { window });
return;
}
+ if ipc_win.layout != window_layout {
+ batch_change_layouts.push((id, window_layout));
+ }
+
if mapped.is_focused() && !ipc_win.is_focused {
events.push(Event::WindowFocusChanged { id: Some(id) });
}
@@ -698,6 +710,17 @@ impl State {
}
});
+ // It might make sense to push layout changes after closed windows (since windows about to
+ // be closed will occupy the same column/tile positions as the window that moved into this
+ // vacated space), but also we are already pushing some layout changes in
+ // WindowOpenedOrChanged above, meaning that the receiving end has to handle this case
+ // anyway.
+ if !batch_change_layouts.is_empty() {
+ events.push(Event::WindowLayoutsChanged {
+ changes: batch_change_layouts,
+ });
+ }
+
// Check for closed windows.
let mut ipc_focused_id = None;
for (id, ipc_win) in &state.windows {