Move send_pending_configure out of new_toplevel()

This commit is contained in:
Seaotatop 2023-05-30 20:47:12 -05:00
parent 4b32c2f454
commit caa6930cd5
4 changed files with 129 additions and 53 deletions

View file

@ -11,6 +11,7 @@ use smithay::{
Client,
},
},
utils::Serial,
wayland::{
buffer::BufferHandler,
compositor::{self, CompositorClientState, CompositorHandler, CompositorState},
@ -43,17 +44,31 @@ impl CompositorHandler for State {
}
fn commit(&mut self, surface: &WlSurface) {
// println!("CompositorHandler commit()");
utils::on_commit_buffer_handler::<Self>(surface);
if !compositor::is_sync_subsurface(surface) {
let mut root = surface.clone();
while let Some(parent) = compositor::get_parent(&root) {
root = parent;
}
if let Some(window) = self
.space
.elements()
.find(|w| w.toplevel().wl_surface() == &root)
{
// println!("window.on_commit");
window.on_commit();
}
};
if let Some(window) = self
.space
.elements()
.find(|w| w.toplevel().wl_surface() == surface)
.cloned()
{
// TODO: from smallvil: check if subsurfaces are synced then do on_commit or something
window.on_commit();
let initial_configure_sent = compositor::with_states(surface, |states| {
states
.data_map
@ -63,8 +78,10 @@ impl CompositorHandler for State {
.unwrap()
.initial_configure_sent
});
// println!("initial_configure_sent is {}", initial_configure_sent);
if !initial_configure_sent {
// println!("initial configure");
window.toplevel().send_configure();
}
}
@ -96,16 +113,11 @@ impl SeatHandler for State {
&mut self.seat_state
}
fn cursor_image(&mut self, _seat: &smithay::input::Seat<Self>, _image: CursorImageStatus) {
self.cursor_status = _image;
fn cursor_image(&mut self, _seat: &Seat<Self>, image: CursorImageStatus) {
self.cursor_status = image;
}
fn focus_changed(
&mut self,
_seat: &smithay::input::Seat<Self>,
_focused: Option<&Self::KeyboardFocus>,
) {
}
fn focus_changed(&mut self, _seat: &Seat<Self>, _focused: Option<&Self::KeyboardFocus>) {}
}
delegate_seat!(State);
@ -128,6 +140,7 @@ impl XdgShellHandler for State {
let windows: Vec<Window> = self.space.elements().cloned().collect();
let layout = MasterStack {
windows: Vec::new(),
side: MasterStackSide::Left,
};
@ -139,6 +152,7 @@ impl XdgShellHandler for State {
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
let windows: Vec<Window> = self.space.elements().cloned().collect();
let layout = MasterStack {
windows: Vec::new(),
side: MasterStackSide::Left,
};
@ -148,12 +162,7 @@ impl XdgShellHandler for State {
fn new_popup(&mut self, surface: PopupSurface, positioner: PositionerState) {}
fn move_request(
&mut self,
surface: ToplevelSurface,
seat: WlSeat,
serial: smithay::utils::Serial,
) {
fn move_request(&mut self, surface: ToplevelSurface, seat: WlSeat, serial: Serial) {
crate::xdg::request::move_request(
self,
&surface,
@ -166,7 +175,7 @@ impl XdgShellHandler for State {
&mut self,
surface: ToplevelSurface,
seat: WlSeat,
serial: smithay::utils::Serial,
serial: Serial,
edges: ResizeEdge,
) {
const BUTTON_LEFT: u32 = 0x110;
@ -180,7 +189,7 @@ impl XdgShellHandler for State {
);
}
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: smithay::utils::Serial) {}
fn grab(&mut self, surface: PopupSurface, seat: WlSeat, serial: Serial) {}
// TODO: impl the rest of the fns in XdgShellHandler
}

View file

@ -1,3 +1,5 @@
use std::{error::Error, fmt::Display};
use smithay::desktop::Window;
use crate::State;
@ -7,4 +9,20 @@ pub mod manual;
pub trait Layout {
fn layout_windows(&self, state: &mut State, windows: Vec<Window>);
fn add_window(&mut self, state: &mut State, window: Window);
fn remove_window(&mut self, state: &mut State, window: Window)
-> Result<(), RemoveWindowError>;
}
#[derive(Debug)]
pub enum RemoveWindowError {
NotFound,
}
impl Display for RemoveWindowError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
impl Error for RemoveWindowError {}

View file

@ -2,11 +2,12 @@ use smithay::desktop::Window;
use crate::State;
use super::Layout;
use super::{Layout, RemoveWindowError};
/// A layout which puts one "master" window on one half of the screen and splits other windows
/// among the other half.
pub struct MasterStack {
pub windows: Vec<Window>,
/// Which side of the screen the master window will be on
pub side: MasterStackSide,
}
@ -22,6 +23,7 @@ impl Layout for MasterStack {
fn layout_windows(&self, state: &mut State, windows: Vec<Window>) {
match self.side {
MasterStackSide::Left => {
// println!("MasterStack layout_windows");
let window_count = windows.len();
if window_count == 0 {
return;
@ -40,51 +42,79 @@ impl Layout for MasterStack {
tl_state.size = Some(state.space.output_geometry(&output).unwrap().size);
});
window.toplevel().send_pending_configure();
state
.space
.map_element(window, output.current_location(), false);
return;
}
let mut windows = windows.iter();
let first_window = windows.next().unwrap();
first_window.toplevel().with_pending_state(|tl_state| {
let mut size = state.space.output_geometry(&output).unwrap().size;
size.w /= 2;
tl_state.size = Some(size);
});
// INFO: this is in its own scope to drop the first_window reference so I can
// | move windows into the closure below
{
let mut windows = windows.iter();
let first_window = windows.next().unwrap();
first_window.toplevel().send_pending_configure();
state
.space
.map_element(first_window.clone(), output.current_location(), false);
let window_count = windows.len() as i32;
let height = output_size.h / window_count;
let x = output.current_location().x + output_size.w / 2;
for (i, win) in windows.enumerate() {
win.toplevel().with_pending_state(|state| {
let mut new_size = output_size;
new_size.w /= 2;
new_size.h /= window_count;
state.size = Some(new_size);
first_window.toplevel().with_pending_state(|tl_state| {
let mut size = state.space.output_geometry(&output).unwrap().size;
size.w /= 2;
tl_state.size = Some(size);
});
win.toplevel().send_pending_configure();
state
.space
.map_element(first_window.clone(), output.current_location(), false);
let mut new_loc = output.current_location();
new_loc.x = x;
new_loc.y = i as i32 * height;
let window_count = windows.len() as i32;
let height = output_size.h / window_count;
let x = output.current_location().x + output_size.w / 2;
state.space.map_element(win.clone(), new_loc, false);
for (i, win) in windows.enumerate() {
win.toplevel().with_pending_state(|state| {
let mut new_size = output_size;
new_size.w /= 2;
new_size.h /= window_count;
state.size = Some(new_size);
});
let mut new_loc = output.current_location();
new_loc.x = x;
new_loc.y = i as i32 * height;
state.space.map_element(win.clone(), new_loc, false);
}
}
// INFO: We send configures when the event loop is idle so
// | CompositorHandler::commit() sends the initial configure
state.loop_handle.insert_idle(|_calloop_data| {
for win in windows {
win.toplevel().send_pending_configure();
}
});
}
MasterStackSide::Right => todo!(),
MasterStackSide::Top => todo!(),
MasterStackSide::Bottom => todo!(),
}
}
fn add_window(&mut self, state: &mut State, window: Window) {
self.windows.push(window);
}
fn remove_window(
&mut self,
state: &mut State,
window: Window,
) -> Result<(), RemoveWindowError> {
let pos = self
.windows
.iter()
.position(|win| window == win.clone())
.ok_or(RemoveWindowError::NotFound)?;
self.windows.remove(pos);
Ok(())
}
}

View file

@ -2,6 +2,7 @@ mod grab;
mod handlers;
mod layout;
mod pointer;
mod tag;
mod window;
mod xdg;
@ -180,11 +181,20 @@ fn main() -> Result<(), Box<dyn Error>> {
press_state,
serial,
time,
|_a, _modifiers, keysym| {
|_state, _modifiers, keysym| {
if press_state == KeyState::Pressed
&& keysym.modified_sym() == keysyms::KEY_L
{
println!("pressed L");
FilterResult::Intercept(1)
} else if press_state == KeyState::Pressed
&& keysym.modified_sym() == keysyms::KEY_K
{
FilterResult::Intercept(2)
} else if press_state == KeyState::Pressed
&& keysym.modified_sym() == keysyms::KEY_J
{
FilterResult::Intercept(3)
} else if keysym.modified_sym() == keysyms::KEY_Control_L {
match press_state {
KeyState::Pressed => {
@ -203,8 +213,18 @@ fn main() -> Result<(), Box<dyn Error>> {
state.move_mode = move_mode;
if action == Some(1) {
std::process::Command::new("alacritty").spawn().unwrap();
match action {
Some(1) => {
std::process::Command::new("alacritty").spawn().unwrap();
}
Some(2) => {
std::process::Command::new("nautilus").spawn().unwrap();
}
Some(3) => {
std::process::Command::new("kitty").spawn().unwrap();
}
Some(_) => {}
None => {}
}
}
InputEvent::PointerMotion { event } => {}
@ -268,7 +288,6 @@ fn main() -> Result<(), Box<dyn Error>> {
const BUTTON_RIGHT: u32 = 0x111;
if state.move_mode {
if event.button_code() == BUTTON_LEFT {
// BTN_RIGHT
crate::xdg::request::move_request_force(
state,
window.toplevel(),