aboutsummaryrefslogtreecommitdiff
path: root/src/handlers/compositor.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-08-13 12:46:53 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-08-13 12:46:53 +0400
commit95c810c855a27a28f4dfa7dc6b949fef0901c7b2 (patch)
treec240dd8d8c6eac7cd18c507fbe35724ca7de8aeb /src/handlers/compositor.rs
parente02e35f9c61e103a01640d3dc95a894e8855e1c9 (diff)
downloadniri-95c810c855a27a28f4dfa7dc6b949fef0901c7b2.tar.gz
niri-95c810c855a27a28f4dfa7dc6b949fef0901c7b2.tar.bz2
niri-95c810c855a27a28f4dfa7dc6b949fef0901c7b2.zip
Refactor everything, add initial tiling code
Diffstat (limited to 'src/handlers/compositor.rs')
-rw-r--r--src/handlers/compositor.rs103
1 files changed, 89 insertions, 14 deletions
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs
index f5a955e1..d9e25b8f 100644
--- a/src/handlers/compositor.rs
+++ b/src/handlers/compositor.rs
@@ -1,4 +1,7 @@
-use smithay::backend::renderer::utils::on_commit_buffer_handler;
+use std::collections::hash_map::Entry;
+
+use smithay::backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state};
+use smithay::desktop::find_popup_root_surface;
use smithay::reexports::wayland_server::protocol::wl_buffer;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::reexports::wayland_server::Client;
@@ -9,6 +12,7 @@ use smithay::wayland::compositor::{
use smithay::wayland::shm::{ShmHandler, ShmState};
use smithay::{delegate_compositor, delegate_shm};
+use super::xdg_shell;
use crate::grabs::resize_grab;
use crate::niri::ClientState;
use crate::Niri;
@@ -28,24 +32,95 @@ impl CompositorHandler for Niri {
.message("client commit", 0);
on_commit_buffer_handler::<Self>(surface);
- if !is_sync_subsurface(surface) {
- let mut root = surface.clone();
- while let Some(parent) = get_parent(&root) {
- root = parent;
+
+ if is_sync_subsurface(surface) {
+ return;
+ }
+
+ let mut root_surface = surface.clone();
+ while let Some(parent) = get_parent(&root_surface) {
+ root_surface = parent;
+ }
+
+ if surface == &root_surface {
+ // This is a root surface commit. It might have mapped a previously-unmapped toplevel.
+ if let Entry::Occupied(entry) = self.unmapped_windows.entry(surface.clone()) {
+ let is_mapped =
+ with_renderer_surface_state(surface, |state| state.buffer().is_some());
+
+ if is_mapped {
+ // The toplevel got mapped.
+ let window = entry.remove();
+ window.on_commit();
+
+ let output = self.monitor_set.active_output().unwrap().clone();
+ self.monitor_set.add_window_to_output(&output, window, true);
+ self.update_focus();
+
+ self.queue_redraw(output);
+ return;
+ }
+
+ // The toplevel remains unmapped.
+ let window = entry.get();
+ xdg_shell::send_initial_configure_if_needed(window);
+ return;
}
- if let Some(window) = self
- .space
- .elements()
- .find(|w| w.toplevel().wl_surface() == &root)
- {
+
+ // This is a commit of a previously-mapped root or a non-toplevel root.
+ if let Some((window, space)) = self.monitor_set.find_window_and_space(surface) {
+ // This is a commit of a previously-mapped toplevel.
+ let output = space.outputs().next().unwrap().clone();
+
window.on_commit();
+
+ // This is a commit of a previously-mapped toplevel.
+ let is_mapped =
+ with_renderer_surface_state(surface, |state| state.buffer().is_some());
+
+ if !is_mapped {
+ // The toplevel got unmapped.
+ let window = window.clone();
+ self.monitor_set.remove_window(&window);
+ self.unmapped_windows.insert(surface.clone(), window);
+ self.update_focus();
+
+ self.queue_redraw(output);
+ return;
+ }
+
+ // The toplevel remains mapped.
+ resize_grab::handle_commit(&window);
+ self.monitor_set.update_window(&window);
+
+ self.queue_redraw(output);
+ return;
}
- };
- self.xdg_handle_commit(surface);
- resize_grab::handle_commit(&mut self.space, surface);
+ // This is a commit of a non-toplevel root.
+ }
- self.queue_redraw();
+ // This is a commit of a non-root or a non-toplevel root.
+ let root_window_space = self.monitor_set.find_window_and_space(&root_surface);
+ if let Some((window, space)) = root_window_space {
+ let output = space.outputs().next().unwrap().clone();
+ window.on_commit();
+ self.monitor_set.update_window(&window);
+ self.queue_redraw(output);
+ return;
+ }
+
+ // This might be a popup.
+ self.popups_handle_commit(surface);
+ if let Some(popup) = self.popups.find_popup(surface) {
+ if let Ok(root) = find_popup_root_surface(&popup) {
+ let root_window_space = self.monitor_set.find_window_and_space(&root);
+ if let Some((_window, space)) = root_window_space {
+ let output = space.outputs().next().unwrap().clone();
+ self.queue_redraw(output);
+ }
+ }
+ }
}
}