diff --git a/api/lua/pinnacle-api-dev-1.rockspec b/api/lua/pinnacle-api-dev-1.rockspec index 13e56f9..ef7d345 100644 --- a/api/lua/pinnacle-api-dev-1.rockspec +++ b/api/lua/pinnacle-api-dev-1.rockspec @@ -24,6 +24,7 @@ build = { ["pinnacle.output"] = "pinnacle/output.lua", ["pinnacle.process"] = "pinnacle/process.lua", ["pinnacle.tag"] = "pinnacle/tag.lua", + ["pinnacle.tag.layout"] = "pinnacle/tag/layout.lua", ["pinnacle.window"] = "pinnacle/window.lua", ["pinnacle.util"] = "pinnacle/util.lua", ["pinnacle.signal"] = "pinnacle/signal.lua", diff --git a/api/lua/pinnacle/grpc/client.lua b/api/lua/pinnacle/grpc/client.lua index 7cbaacd..5382fd7 100644 --- a/api/lua/pinnacle/grpc/client.lua +++ b/api/lua/pinnacle/grpc/client.lua @@ -42,6 +42,8 @@ end ---@field new_stream function ---@class H2Stream +---@field write_chunk function +---@field shutdown function ---@nodoc ---@class Client @@ -202,8 +204,6 @@ function client.bidirectional_streaming_request(grpc_request_params, callback) print(name, value, never_index) end end - - print("AFTER bidirectional_streaming_request ENDS") end) return stream diff --git a/api/lua/pinnacle/output.lua b/api/lua/pinnacle/output.lua index b35da69..ff0e90b 100644 --- a/api/lua/pinnacle/output.lua +++ b/api/lua/pinnacle/output.lua @@ -166,6 +166,29 @@ function output.connect_for_all(callback) end) end +---@class OutputSignal +---@field connect fun(output: OutputHandle)? + +---@param signals OutputSignal +---@return SignalHandles +function output.connect_signal(signals) + ---@diagnostic disable-next-line: invisible + local handles = require("pinnacle.signal").handles.new({}) + + for signal, callback in pairs(signals) do + if signal == "connect" then + require("pinnacle.signal").add_callback("OutputConnect", callback) + ---@diagnostic disable-next-line: invisible + local handle = require("pinnacle.signal").handle.new("OutputConnect", callback) + handles[signal] = handle + end + end + + return handles +end + +--------------------------------------------------------------------- + ---Set the location of this output in the global space. --- ---On startup, Pinnacle will lay out all connected outputs starting at (0, 0) diff --git a/api/lua/pinnacle/signal.lua b/api/lua/pinnacle/signal.lua index 4783064..4ed7110 100644 --- a/api/lua/pinnacle/signal.lua +++ b/api/lua/pinnacle/signal.lua @@ -49,108 +49,156 @@ local stream_control = { DISCONNECT = 2, } +---@type table local signals = { - output_connect = { + OutputConnect = { ---@type H2Stream? sender = nil, ---@type (fun(output: OutputHandle))[] callbacks = {}, + ---@type fun(response: table) + on_response = nil, }, - layout = { + Layout = { ---@type H2Stream? sender = nil, - ---@type (fun(windows: WindowHandle[], tag: TagHandle))[] + ---@type (fun(tag: TagHandle, windows: WindowHandle[]))[] callbacks = {}, + ---@type fun(response: table) + on_response = nil, }, - window_pointer_enter = { + WindowPointerEnter = { ---@type H2Stream? sender = nil, ---@type (fun(output: OutputHandle))[] callbacks = {}, + ---@type fun(response: table) + on_response = nil, }, - window_pointer_leave = { + WindowPointerLeave = { ---@type H2Stream? sender = nil, ---@type (fun(output: OutputHandle))[] callbacks = {}, + ---@type fun(response: table) + on_response = nil, }, } +signals.OutputConnect.on_response = function(response) + ---@diagnostic disable-next-line: invisible + local handle = require("pinnacle.output").handle.new(response.output_name) + for _, callback in ipairs(signals.OutputConnect.callbacks) do + callback(handle) + end +end + +signals.Layout.on_response = function(response) + ---@diagnostic disable-next-line: invisible + local window_handles = require("pinnacle.window").handle.new_from_table(response.window_ids or {}) + ---@diagnostic disable-next-line: invisible + local tag_handle = require("pinnacle.tag").handle.new(response.tag_id) + + for _, callback in ipairs(signals.Layout.callbacks) do + callback(tag_handle, window_handles) + end +end + +----------------------------------------------------------------------------- + +---@class SignalHandleModule +local signal_handle = {} + +---@class SignalHandle +---@field signal SignalServiceMethod +---@field callback function The callback you connected +local SignalHandle = {} + +---@class SignalHandlesModule +local signal_handles = {} + +---@class SignalHandles +local SignalHandles = {} + ---@class Signal +---@field private handle SignalHandleModule +---@field private handles SignalHandlesModule local signal = {} +signal.handle = signal_handle +signal.handles = signal_handles ----@param fn fun(windows: WindowHandle[], tag: TagHandle) -function signal.layout_add(fn) - if #signals.layout.callbacks == 0 then - signal.layout_connect() - end - - table.insert(signals.layout.callbacks, fn) -end - -function signal.layout_dc() - signal.layout_disconnect() -end - -function signal.output_connect_connect() - local stream = client.bidirectional_streaming_request( - build_grpc_request_params("OutputConnect", { - control = stream_control.READY, - }), - function(response) - ---@diagnostic disable-next-line: invisible - local handle = require("pinnacle.output").handle.new(response.output_name) - for _, callback in ipairs(signals.output_connect.callbacks) do - callback(handle) - end - - local chunk = require("pinnacle.grpc.protobuf").encode(prefix .. "OutputConnectRequest", { - control = stream_control.READY, - }) - - if signals.layout.sender then - signals.layout.sender:write_chunk(chunk) - end +function SignalHandle:disconnect() + local cb_index = nil + for i, cb in ipairs(signals[self.signal].callbacks) do + if cb == self.callback then + cb_index = i + break end - ) + end - signals.output_connect.sender = stream -end + if cb_index then + table.remove(signals[self.signal].callbacks, cb_index) + end -function signal.output_connect_disconnect() - if signals.output_connect.sender then - local chunk = require("pinnacle.grpc.protobuf").encode(prefix .. "OutputConnectRequest", { - control = stream_control.DISCONNECT, - }) - - signals.output_connect.sender:write_chunk(chunk) - signals.output_connect.sender = nil + if #signals[self.signal].callbacks == 0 then + signal.disconnect(self.signal) end end -function signal.layout_connect() +---@return SignalHandle +function signal_handle.new(request, callback) + ---@type SignalHandle + local self = { + signal = request, + callback = callback, + } + setmetatable(self, { __index = SignalHandle }) + return self +end + +---@param self table +function SignalHandles:disconnect_all() + for _, sig in pairs(self) do + sig:disconnect() + end +end + +---@param signal_hdls table +---@return SignalHandles +function signal_handles.new(signal_hdls) + ---@type SignalHandles + local self = signal_hdls + setmetatable(self, { __index = SignalHandles }) + return self +end + +---@param request SignalServiceMethod +---@param callback function +function signal.add_callback(request, callback) + if #signals[request].callbacks == 0 then + signal.connect(request, signals[request].on_response) + end + + table.insert(signals[request].callbacks, callback) +end + +---@param request SignalServiceMethod +---@param callback fun(response: table) +function signal.connect(request, callback) local stream = client.bidirectional_streaming_request( build_grpc_request_params("Layout", { control = stream_control.READY, }), function(response) - ---@diagnostic disable-next-line: invisible - local window_handles = require("pinnacle.window").handle.new_from_table(response.window_ids or {}) - ---@diagnostic disable-next-line: invisible - local tag_handle = require("pinnacle.tag").handle.new(response.tag_id) + callback(response) - for _, callback in ipairs(signals.layout.callbacks) do - print("calling layout callback") - callback(window_handles, tag_handle) - end + if signals[request].sender then + local chunk = require("pinnacle.grpc.protobuf").encode(prefix .. request .. "Request", { + control = stream_control.READY, + }) - print("creating control request") - local chunk = require("pinnacle.grpc.protobuf").encode(prefix .. "LayoutRequest", { - control = stream_control.READY, - }) + local success, err = pcall(signals[request].sender.write_chunk, signals[request].sender, chunk) - if signals.layout.sender then - local success, err = pcall(signals.layout.sender.write_chunk, signals.layout.sender, chunk) if not success then print("error sending to stream:", err) os.exit(1) @@ -159,19 +207,26 @@ function signal.layout_connect() end ) - signals.layout.sender = stream + signals[request].sender = stream end -function signal.layout_disconnect() - if signals.layout.sender then - local chunk = require("pinnacle.grpc.protobuf").encode(prefix .. "LayoutRequest", { +---This should only be called when call callbacks for the signal are removed +---@param request SignalServiceMethod +function signal.disconnect(request) + if signals[request].sender then + local chunk = require("pinnacle.grpc.protobuf").encode(prefix .. request .. "Request", { control = stream_control.DISCONNECT, }) - signals.layout.sender:write_chunk(chunk) - signals.layout.sender = nil + local success, err = pcall(signals[request].sender.write_chunk, signals[request].sender, chunk) + if not success then + print("error sending to stream:", err) + os.exit(1) + end + + signals[request].sender:shutdown() + signals[request].sender = nil end - signals.layout.callbacks = {} end return signal diff --git a/api/lua/pinnacle/tag.lua b/api/lua/pinnacle/tag.lua index e1b61d2..7e2fbd7 100644 --- a/api/lua/pinnacle/tag.lua +++ b/api/lua/pinnacle/tag.lua @@ -319,9 +319,25 @@ function tag.new_layout_cycler(layouts) } end ----@param fn fun(windows: WindowHandle[], tag: TagHandle) -function tag.connect_layout(fn) - require("pinnacle.signal").layout_add(fn) +---@class TagSignal +---@field layout fun(tag: TagHandle, windows: WindowHandle[])? + +---@param signals TagSignal +---@return SignalHandles +function tag.connect_signal(signals) + ---@diagnostic disable-next-line: invisible + local handles = require("pinnacle.signal").handles.new({}) + + for signal, callback in pairs(signals) do + if signal == "layout" then + require("pinnacle.signal").add_callback("Layout", callback) + ---@diagnostic disable-next-line: invisible + local handle = require("pinnacle.signal").handle.new("Layout", callback) + handles[signal] = handle + end + end + + return handles end ---Remove this tag. diff --git a/api/lua/pinnacle/tag/layout.lua b/api/lua/pinnacle/tag/layout.lua new file mode 100644 index 0000000..b184211 --- /dev/null +++ b/api/lua/pinnacle/tag/layout.lua @@ -0,0 +1,4 @@ +---@class LayoutModule +local layout = {} + +return layout diff --git a/src/api.rs b/src/api.rs index 92887b2..d91f610 100644 --- a/src/api.rs +++ b/src/api.rs @@ -128,7 +128,7 @@ where fn run_bidirectional_streaming( fn_sender: StateFnSender, mut in_stream: Streaming, - with_client_item: F1, + with_client_request: F1, with_out_stream: F2, ) -> Result>, Status> where @@ -142,11 +142,11 @@ where let fn_sender_clone = fn_sender.clone(); let with_in_stream = async move { - while let Some(t) = in_stream.next().await { - let with_client_item = with_client_item.clone(); + while let Some(request) = in_stream.next().await { + let with_client_request = with_client_request.clone(); // TODO: handle error let _ = fn_sender_clone.send(Box::new(move |state: &mut State| { - with_client_item(state, t); + with_client_request(state, request); })); } }; @@ -734,11 +734,13 @@ impl tag_service_server::TagService for TagService { state.update_focus(&output); state.schedule_render(&output); - state.signal_state.layout.signal(|_| { - pinnacle_api_defs::pinnacle::signal::v0alpha1::LayoutResponse { - window_ids: vec![1, 2, 3], - tag_id: Some(1), - } + state.signal_state.layout.signal(|buffer| { + buffer.push_back( + pinnacle_api_defs::pinnacle::signal::v0alpha1::LayoutResponse { + window_ids: vec![1, 2, 3], + tag_id: Some(1), + }, + ); }); }) .await @@ -1125,7 +1127,7 @@ impl window_service_server::WindowService for WindowService { async fn close(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, @@ -1154,7 +1156,7 @@ impl window_service_server::WindowService for WindowService { tracing::info!(request = ?request); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, @@ -1205,7 +1207,7 @@ impl window_service_server::WindowService for WindowService { ) -> Result, Status> { let request = request.into_inner(); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, @@ -1248,7 +1250,7 @@ impl window_service_server::WindowService for WindowService { ) -> Result, Status> { let request = request.into_inner(); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, @@ -1291,7 +1293,7 @@ impl window_service_server::WindowService for WindowService { ) -> Result, Status> { let request = request.into_inner(); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, @@ -1334,7 +1336,7 @@ impl window_service_server::WindowService for WindowService { ) -> Result, Status> { let request = request.into_inner(); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, @@ -1362,7 +1364,7 @@ impl window_service_server::WindowService for WindowService { async fn set_tag(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, @@ -1518,12 +1520,7 @@ impl window_service_server::WindowService for WindowService { let window_ids = state .windows .iter() - .map(|win| { - win.with_state(|state| match state.id { - WindowId::None => unreachable!(), - WindowId::Some(id) => id, - }) - }) + .map(|win| win.with_state(|state| state.id.0)) .collect::>(); window::v0alpha1::GetResponse { window_ids } @@ -1537,7 +1534,7 @@ impl window_service_server::WindowService for WindowService { ) -> Result, Status> { let request = request.into_inner(); - let window_id = WindowId::Some( + let window_id = WindowId( request .window_id .ok_or_else(|| Status::invalid_argument("no window specified"))?, diff --git a/src/api/signal.rs b/src/api/signal.rs index 452982c..0bfeaaa 100644 --- a/src/api/signal.rs +++ b/src/api/signal.rs @@ -1,3 +1,5 @@ +use std::collections::VecDeque; + use pinnacle_api_defs::pinnacle::signal::v0alpha1::{ signal_service_server, LayoutRequest, LayoutResponse, OutputConnectRequest, OutputConnectResponse, StreamControl, WindowPointerEnterRequest, WindowPointerEnterResponse, @@ -12,33 +14,61 @@ use super::{run_bidirectional_streaming, ResponseStream, StateFnSender}; #[derive(Debug, Default)] pub struct SignalState { - pub output_connect: SignalData, - pub layout: SignalData, - pub window_pointer_enter: SignalData, - pub window_pointer_leave: SignalData, + pub output_connect: SignalData>, + pub layout: SignalData>, + pub window_pointer_enter: + SignalData>, + pub window_pointer_leave: + SignalData>, } #[derive(Debug, Default)] -pub struct SignalData { +#[allow(private_bounds)] +pub struct SignalData> { sender: Option>>, join_handle: Option>, ready: bool, - value: Option, + buffer: B, } -impl SignalData { - pub fn signal(&mut self, with_data: impl FnOnce(Option) -> T) { +/// A trait that denotes different types of containers that can be used to buffer signals. +trait SignalBuffer: Default { + /// Get the next signal from this buffer. + fn next(&mut self) -> Option; +} + +impl SignalBuffer for VecDeque { + fn next(&mut self) -> Option { + self.pop_front() + } +} + +impl SignalBuffer for Option { + fn next(&mut self) -> Option { + self.take() + } +} + +#[allow(private_bounds)] +impl> SignalData { + /// Attempt to send a signal. + /// + /// If the client is ready to accept more of this signal, it will be sent immediately. + /// Otherwise, the signal will remain stored in the underlying buffer until the client is ready. + /// + /// Use `with_buffer` to populate and manipulate the buffer with the data you want. + pub fn signal(&mut self, with_buffer: impl FnOnce(&mut B)) { let Some(sender) = self.sender.as_ref() else { return; }; + with_buffer(&mut self.buffer); + if self.ready { - sender - .send(Ok(with_data(self.value.take()))) - .expect("failed to send signal"); - self.ready = false; - } else { - self.value = Some(with_data(self.value.take())); + if let Some(data) = self.buffer.next() { + sender.send(Ok(data)).expect("failed to send signal"); + self.ready = false; + } } } @@ -59,16 +89,19 @@ impl SignalData { handle.abort(); } self.ready = false; - self.value.take(); + self.buffer = B::default(); } + /// Mark this signal as ready to send. + /// + /// If there are signals already in the buffer, they will be sent. fn ready(&mut self) { let Some(sender) = self.sender.as_ref() else { return; }; - if let Some(value) = self.value.take() { - sender.send(Ok(value)).expect("failed to send signal"); + if let Some(data) = self.buffer.next() { + sender.send(Ok(data)).expect("failed to send signal"); self.ready = false; } else { self.ready = true; @@ -99,16 +132,18 @@ impl_signal_request!( WindowPointerLeaveRequest ); -fn start_signal_stream( +fn start_signal_stream( sender: StateFnSender, in_stream: Streaming, - signal: impl Fn(&mut State) -> &mut SignalData + Clone + Send + 'static, + with_signal_buffer: F, ) -> Result>, Status> where - I: Send + 'static, + I: SignalRequest + std::fmt::Debug + Send + 'static, O: Send + 'static, + B: SignalBuffer, + F: Fn(&mut State) -> &mut SignalData + Clone + Send + 'static, { - let signal_clone = signal.clone(); + let with_signal_buffer_clone = with_signal_buffer.clone(); run_bidirectional_streaming( sender, @@ -122,9 +157,9 @@ where } }; - tracing::info!("GOT {request:?} FROM CLIENT STREAM"); + tracing::debug!("Got {request:?} from client stream"); - let signal = signal(state); + let signal = with_signal_buffer(state); match request.control() { StreamControl::Ready => signal.ready(), StreamControl::Disconnect => signal.disconnect(), @@ -132,7 +167,7 @@ where } }, move |state, sender, join_handle| { - let signal = signal_clone(state); + let signal = with_signal_buffer_clone(state); signal.connect(sender, join_handle); }, ) diff --git a/src/backend/udev.rs b/src/backend/udev.rs index e3948cc..e4339ab 100644 --- a/src/backend/udev.rs +++ b/src/backend/udev.rs @@ -8,7 +8,9 @@ use std::{ }; use anyhow::Context; -use pinnacle_api_defs::pinnacle::output::v0alpha1::ConnectForAllResponse; +use pinnacle_api_defs::pinnacle::{ + output::v0alpha1::ConnectForAllResponse, signal::v0alpha1::OutputConnectResponse, +}; use smithay::{ backend::{ allocator::{ @@ -989,6 +991,12 @@ impl State { output_name: Some(output.name()), })); } + + self.signal_state.output_connect.signal(|buffer| { + buffer.push_back(OutputConnectResponse { + output_name: Some(output.name()), + }) + }); } } diff --git a/src/window.rs b/src/window.rs index 7cb43a9..c20f973 100644 --- a/src/window.rs +++ b/src/window.rs @@ -4,6 +4,9 @@ pub mod rules; use std::{cell::RefCell, time::Duration}; +use pinnacle_api_defs::pinnacle::signal::v0alpha1::{ + WindowPointerEnterResponse, WindowPointerLeaveResponse, +}; use smithay::{ backend::input::KeyState, desktop::{ @@ -330,33 +333,40 @@ impl WindowElement { } impl PointerTarget for WindowElement { - fn frame(&self, seat: &Seat, data: &mut State) { + fn frame(&self, seat: &Seat, state: &mut State) { match self { - WindowElement::Wayland(window) => window.frame(seat, data), + WindowElement::Wayland(window) => window.frame(seat, state), WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - surface.frame(seat, data) + surface.frame(seat, state) } _ => unreachable!(), } } - fn enter(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { + fn enter(&self, seat: &Seat, state: &mut State, event: &MotionEvent) { // TODO: ssd match self { - WindowElement::Wayland(window) => PointerTarget::enter(window, seat, data, event), + WindowElement::Wayland(window) => PointerTarget::enter(window, seat, state, event), WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - PointerTarget::enter(surface, seat, data, event) + PointerTarget::enter(surface, seat, state, event) } _ => unreachable!(), } + + let window_id = Some(self.with_state(|state| state.id.0)); + + state + .signal_state + .window_pointer_enter + .signal(|buffer| buffer.push_back(WindowPointerEnterResponse { window_id })); } - fn motion(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { + fn motion(&self, seat: &Seat, state: &mut State, event: &MotionEvent) { // TODO: ssd match self { - WindowElement::Wayland(window) => PointerTarget::motion(window, seat, data, event), + WindowElement::Wayland(window) => PointerTarget::motion(window, seat, state, event), WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - PointerTarget::motion(surface, seat, data, event) + PointerTarget::motion(surface, seat, state, event) } _ => unreachable!(), } @@ -365,16 +375,16 @@ impl PointerTarget for WindowElement { fn relative_motion( &self, seat: &Seat, - data: &mut State, + state: &mut State, event: &smithay::input::pointer::RelativeMotionEvent, ) { // TODO: ssd match self { WindowElement::Wayland(window) => { - PointerTarget::relative_motion(window, seat, data, event); + PointerTarget::relative_motion(window, seat, state, event); } WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - PointerTarget::relative_motion(surface, seat, data, event); + PointerTarget::relative_motion(surface, seat, state, event); } _ => unreachable!(), } @@ -383,47 +393,54 @@ impl PointerTarget for WindowElement { fn button( &self, seat: &Seat, - data: &mut State, + state: &mut State, event: &smithay::input::pointer::ButtonEvent, ) { // TODO: ssd match self { - WindowElement::Wayland(window) => PointerTarget::button(window, seat, data, event), + WindowElement::Wayland(window) => PointerTarget::button(window, seat, state, event), WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - PointerTarget::button(surface, seat, data, event) + PointerTarget::button(surface, seat, state, event) } _ => unreachable!(), } } - fn axis(&self, seat: &Seat, data: &mut State, frame: AxisFrame) { + fn axis(&self, seat: &Seat, state: &mut State, frame: AxisFrame) { // TODO: ssd match self { - WindowElement::Wayland(window) => PointerTarget::axis(window, seat, data, frame), + WindowElement::Wayland(window) => PointerTarget::axis(window, seat, state, frame), WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - PointerTarget::axis(surface, seat, data, frame) + PointerTarget::axis(surface, seat, state, frame) } _ => unreachable!(), } } - fn leave(&self, seat: &Seat, data: &mut State, serial: Serial, time: u32) { + fn leave(&self, seat: &Seat, state: &mut State, serial: Serial, time: u32) { // TODO: ssd match self { WindowElement::Wayland(window) => { - PointerTarget::leave(window, seat, data, serial, time); + PointerTarget::leave(window, seat, state, serial, time); } WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - PointerTarget::leave(surface, seat, data, serial, time) + PointerTarget::leave(surface, seat, state, serial, time) } _ => unreachable!(), } + + let window_id = Some(self.with_state(|state| state.id.0)); + + state + .signal_state + .window_pointer_leave + .signal(|buffer| buffer.push_back(WindowPointerLeaveResponse { window_id })); } fn gesture_swipe_begin( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GestureSwipeBeginEvent, ) { todo!() @@ -432,7 +449,7 @@ impl PointerTarget for WindowElement { fn gesture_swipe_update( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GestureSwipeUpdateEvent, ) { todo!() @@ -441,7 +458,7 @@ impl PointerTarget for WindowElement { fn gesture_swipe_end( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GestureSwipeEndEvent, ) { todo!() @@ -450,7 +467,7 @@ impl PointerTarget for WindowElement { fn gesture_pinch_begin( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GesturePinchBeginEvent, ) { todo!() @@ -459,7 +476,7 @@ impl PointerTarget for WindowElement { fn gesture_pinch_update( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GesturePinchUpdateEvent, ) { todo!() @@ -468,7 +485,7 @@ impl PointerTarget for WindowElement { fn gesture_pinch_end( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GesturePinchEndEvent, ) { todo!() @@ -477,7 +494,7 @@ impl PointerTarget for WindowElement { fn gesture_hold_begin( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GestureHoldBeginEvent, ) { todo!() @@ -486,7 +503,7 @@ impl PointerTarget for WindowElement { fn gesture_hold_end( &self, _seat: &Seat, - _data: &mut State, + _state: &mut State, _event: &smithay::input::pointer::GestureHoldEndEvent, ) { todo!() @@ -497,26 +514,26 @@ impl KeyboardTarget for WindowElement { fn enter( &self, seat: &Seat, - data: &mut State, + state: &mut State, keys: Vec>, serial: Serial, ) { match self { WindowElement::Wayland(window) => { - KeyboardTarget::enter(window, seat, data, keys, serial); + KeyboardTarget::enter(window, seat, state, keys, serial); } WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - KeyboardTarget::enter(surface, seat, data, keys, serial) + KeyboardTarget::enter(surface, seat, state, keys, serial) } _ => unreachable!(), } } - fn leave(&self, seat: &Seat, data: &mut State, serial: Serial) { + fn leave(&self, seat: &Seat, state: &mut State, serial: Serial) { match self { - WindowElement::Wayland(window) => KeyboardTarget::leave(window, seat, data, serial), + WindowElement::Wayland(window) => KeyboardTarget::leave(window, seat, state, serial), WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - KeyboardTarget::leave(surface, seat, data, serial) + KeyboardTarget::leave(surface, seat, state, serial) } _ => unreachable!(), } @@ -525,18 +542,18 @@ impl KeyboardTarget for WindowElement { fn key( &self, seat: &Seat, - data: &mut State, + state: &mut State, key: KeysymHandle<'_>, - state: KeyState, + key_state: KeyState, serial: Serial, time: u32, ) { match self { WindowElement::Wayland(window) => { - KeyboardTarget::key(window, seat, data, key, state, serial, time); + KeyboardTarget::key(window, seat, state, key, key_state, serial, time); } WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - KeyboardTarget::key(surface, seat, data, key, state, serial, time); + KeyboardTarget::key(surface, seat, state, key, key_state, serial, time); } _ => unreachable!(), } @@ -545,16 +562,16 @@ impl KeyboardTarget for WindowElement { fn modifiers( &self, seat: &Seat, - data: &mut State, + state: &mut State, modifiers: ModifiersState, serial: Serial, ) { match self { WindowElement::Wayland(window) => { - KeyboardTarget::modifiers(window, seat, data, modifiers, serial); + KeyboardTarget::modifiers(window, seat, state, modifiers, serial); } WindowElement::X11(surface) | WindowElement::X11OverrideRedirect(surface) => { - KeyboardTarget::modifiers(surface, seat, data, modifiers, serial); + KeyboardTarget::modifiers(surface, seat, state, modifiers, serial); } _ => unreachable!(), } diff --git a/src/window/window_state.rs b/src/window/window_state.rs index 69a3f52..e9db349 100644 --- a/src/window/window_state.rs +++ b/src/window/window_state.rs @@ -17,20 +17,14 @@ use super::WindowElement; /// A unique identifier for each window. #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -pub enum WindowId { - /// A config API returned an invalid window. It should be using this variant. - None, - /// A valid window id. - #[serde(untagged)] - Some(u32), -} +pub struct WindowId(pub u32); static WINDOW_ID_COUNTER: AtomicU32 = AtomicU32::new(0); impl WindowId { /// Get the next available window id. This always starts at 0. pub fn next() -> Self { - Self::Some(WINDOW_ID_COUNTER.fetch_add(1, Ordering::Relaxed)) + Self(WINDOW_ID_COUNTER.fetch_add(1, Ordering::Relaxed)) } /// Get the window that has this WindowId.