mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-29 20:34:46 +01:00
Split off backend and rest of State
Currently doesn't clean up anything, still need to change `impl State`s to `impl Pinnacle`s
This commit is contained in:
parent
c9012cf483
commit
8aaec59452
31 changed files with 770 additions and 514 deletions
61
src/api.rs
61
src/api.rs
|
@ -204,7 +204,9 @@ impl pinnacle_service_server::PinnacleService for PinnacleService {
|
|||
run_unary_no_response(&self.sender, |state| {
|
||||
info!("Reloading config");
|
||||
state
|
||||
.start_config(Some(state.config.dir(&state.xdg_base_dirs)))
|
||||
.start_config(Some(
|
||||
state.pinnacle.config.dir(&state.pinnacle.xdg_base_dirs),
|
||||
))
|
||||
.expect("failed to restart config");
|
||||
})
|
||||
.await
|
||||
|
@ -220,7 +222,7 @@ impl pinnacle_service_server::PinnacleService for PinnacleService {
|
|||
_request: Request<ShutdownWatchRequest>,
|
||||
) -> Result<Response<Self::ShutdownWatchStream>, Status> {
|
||||
run_server_streaming(&self.sender, |state, sender| {
|
||||
state.config.shutdown_sender.replace(sender);
|
||||
state.pinnacle.config.shutdown_sender.replace(sender);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -291,6 +293,7 @@ impl input_service_server::InputService for InputService {
|
|||
|
||||
run_server_streaming(&self.sender, move |state, sender| {
|
||||
state
|
||||
.pinnacle
|
||||
.input_state
|
||||
.keybinds
|
||||
.insert((modifiers, keysym), sender);
|
||||
|
@ -334,6 +337,7 @@ impl input_service_server::InputService for InputService {
|
|||
|
||||
run_server_streaming(&self.sender, move |state, sender| {
|
||||
state
|
||||
.pinnacle
|
||||
.input_state
|
||||
.mousebinds
|
||||
.insert((modifiers, button, edge), sender);
|
||||
|
@ -354,7 +358,7 @@ impl input_service_server::InputService for InputService {
|
|||
layout: request.layout(),
|
||||
options: request.options.clone(),
|
||||
};
|
||||
if let Some(kb) = state.seat.get_keyboard() {
|
||||
if let Some(kb) = state.pinnacle.seat.get_keyboard() {
|
||||
if let Err(err) = kb.set_xkb_config(state, new_config) {
|
||||
error!("Failed to set xkbconfig: {err}");
|
||||
}
|
||||
|
@ -377,7 +381,7 @@ impl input_service_server::InputService for InputService {
|
|||
.ok_or_else(|| Status::invalid_argument("no rate specified"))?;
|
||||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
if let Some(kb) = state.seat.get_keyboard() {
|
||||
if let Some(kb) = state.pinnacle.seat.get_keyboard() {
|
||||
kb.change_repeat_info(rate, delay);
|
||||
}
|
||||
})
|
||||
|
@ -518,11 +522,12 @@ impl input_service_server::InputService for InputService {
|
|||
};
|
||||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
for device in state.input_state.libinput_devices.iter_mut() {
|
||||
for device in state.pinnacle.input_state.libinput_devices.iter_mut() {
|
||||
apply_setting(device);
|
||||
}
|
||||
|
||||
state
|
||||
.pinnacle
|
||||
.input_state
|
||||
.libinput_settings
|
||||
.insert(discriminant, apply_setting);
|
||||
|
@ -562,18 +567,19 @@ impl process_service_server::ProcessService for ProcessService {
|
|||
run_server_streaming(&self.sender, move |state, sender| {
|
||||
if once {
|
||||
state
|
||||
.pinnacle
|
||||
.system_processes
|
||||
.refresh_processes_specifics(ProcessRefreshKind::new());
|
||||
|
||||
let compositor_pid = std::process::id();
|
||||
let already_running =
|
||||
state
|
||||
.system_processes
|
||||
.processes_by_exact_name(&arg0)
|
||||
.any(|proc| {
|
||||
proc.parent()
|
||||
.is_some_and(|parent_pid| parent_pid.as_u32() == compositor_pid)
|
||||
});
|
||||
let already_running = state
|
||||
.pinnacle
|
||||
.system_processes
|
||||
.processes_by_exact_name(&arg0)
|
||||
.any(|proc| {
|
||||
proc.parent()
|
||||
.is_some_and(|parent_pid| parent_pid.as_u32() == compositor_pid)
|
||||
});
|
||||
|
||||
if already_running {
|
||||
return;
|
||||
|
@ -743,7 +749,7 @@ impl tag_service_server::TagService for TagService {
|
|||
return;
|
||||
};
|
||||
|
||||
state.fixup_xwayland_internal_z_indices();
|
||||
state.fixup_xwayland_window_layering();
|
||||
|
||||
state.request_layout(&output);
|
||||
state.update_focus(&output);
|
||||
|
@ -772,7 +778,7 @@ impl tag_service_server::TagService for TagService {
|
|||
tag.set_active(true, state);
|
||||
});
|
||||
|
||||
state.fixup_xwayland_internal_z_indices();
|
||||
state.fixup_xwayland_window_layering();
|
||||
|
||||
state.request_layout(&output);
|
||||
state.update_focus(&output);
|
||||
|
@ -804,6 +810,7 @@ impl tag_service_server::TagService for TagService {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
state
|
||||
.pinnacle
|
||||
.config
|
||||
.connector_saved_states
|
||||
.entry(output_name.clone())
|
||||
|
@ -819,7 +826,7 @@ impl tag_service_server::TagService for TagService {
|
|||
}
|
||||
|
||||
for tag in new_tags {
|
||||
for window in state.windows.iter() {
|
||||
for window in state.pinnacle.windows.iter() {
|
||||
window.with_state_mut(|state| {
|
||||
for win_tag in state.tags.iter_mut() {
|
||||
if win_tag.id() == tag.id() {
|
||||
|
@ -844,7 +851,7 @@ impl tag_service_server::TagService for TagService {
|
|||
run_unary_no_response(&self.sender, move |state| {
|
||||
let tags_to_remove = tag_ids.flat_map(|id| id.tag(state)).collect::<Vec<_>>();
|
||||
|
||||
for output in state.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in state.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
// TODO: seriously, convert state.tags into a hashset
|
||||
output.with_state_mut(|state| {
|
||||
for tag_to_remove in tags_to_remove.iter() {
|
||||
|
@ -856,7 +863,7 @@ impl tag_service_server::TagService for TagService {
|
|||
state.schedule_render(&output);
|
||||
}
|
||||
|
||||
for conn_saved_state in state.config.connector_saved_states.values_mut() {
|
||||
for conn_saved_state in state.pinnacle.config.connector_saved_states.values_mut() {
|
||||
for tag_to_remove in tags_to_remove.iter() {
|
||||
conn_saved_state.tags.retain(|tag| tag != tag_to_remove);
|
||||
}
|
||||
|
@ -871,6 +878,7 @@ impl tag_service_server::TagService for TagService {
|
|||
) -> Result<Response<tag::v0alpha1::GetResponse>, Status> {
|
||||
run_unary(&self.sender, move |state| {
|
||||
let tag_ids = state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.flat_map(|op| op.with_state(|state| state.tags.clone()))
|
||||
|
@ -908,6 +916,7 @@ impl tag_service_server::TagService for TagService {
|
|||
.as_ref()
|
||||
.map(|tag| {
|
||||
state
|
||||
.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.filter_map(|win| {
|
||||
|
@ -958,7 +967,12 @@ impl output_service_server::OutputService for OutputService {
|
|||
let y = request.y;
|
||||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
if let Some(saved_state) = state.config.connector_saved_states.get_mut(&output_name) {
|
||||
if let Some(saved_state) = state
|
||||
.pinnacle
|
||||
.config
|
||||
.connector_saved_states
|
||||
.get_mut(&output_name)
|
||||
{
|
||||
if let Some(x) = x {
|
||||
saved_state.loc.x = x;
|
||||
}
|
||||
|
@ -966,7 +980,7 @@ impl output_service_server::OutputService for OutputService {
|
|||
saved_state.loc.y = y;
|
||||
}
|
||||
} else {
|
||||
state.config.connector_saved_states.insert(
|
||||
state.pinnacle.config.connector_saved_states.insert(
|
||||
output_name.clone(),
|
||||
ConnectorSavedState {
|
||||
loc: (x.unwrap_or_default(), y.unwrap_or_default()).into(),
|
||||
|
@ -1100,6 +1114,7 @@ impl output_service_server::OutputService for OutputService {
|
|||
) -> Result<Response<output::v0alpha1::GetResponse>, Status> {
|
||||
run_unary(&self.sender, move |state| {
|
||||
let output_names = state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.map(|output| output.name())
|
||||
|
@ -1135,7 +1150,7 @@ impl output_service_server::OutputService for OutputService {
|
|||
|
||||
let logical_size = output
|
||||
.as_ref()
|
||||
.and_then(|output| state.space.output_geometry(output))
|
||||
.and_then(|output| state.pinnacle.space.output_geometry(output))
|
||||
.map(|geo| (geo.size.w, geo.size.h));
|
||||
|
||||
let current_mode = output
|
||||
|
@ -1267,7 +1282,7 @@ impl render_service_server::RenderService for RenderService {
|
|||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
state.backend.set_upscale_filter(filter);
|
||||
for output in state.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in state.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
state.backend.reset_buffers(&output);
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
|
@ -1292,7 +1307,7 @@ impl render_service_server::RenderService for RenderService {
|
|||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
state.backend.set_downscale_filter(filter);
|
||||
for output in state.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in state.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
state.backend.reset_buffers(&output);
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ impl layout_service_server::LayoutService for LayoutService {
|
|||
}
|
||||
},
|
||||
|state, sender, _join_handle| {
|
||||
state.layout_state.layout_request_sender = Some(sender);
|
||||
state.pinnacle.layout_state.layout_request_sender = Some(sender);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ impl signal_service_server::SignalService for SignalService {
|
|||
let in_stream = request.into_inner();
|
||||
|
||||
start_signal_stream(self.sender.clone(), in_stream, |state| {
|
||||
&mut state.signal_state.output_connect
|
||||
&mut state.pinnacle.signal_state.output_connect
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ impl signal_service_server::SignalService for SignalService {
|
|||
let in_stream = request.into_inner();
|
||||
|
||||
start_signal_stream(self.sender.clone(), in_stream, |state| {
|
||||
&mut state.signal_state.output_disconnect
|
||||
&mut state.pinnacle.signal_state.output_disconnect
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ impl signal_service_server::SignalService for SignalService {
|
|||
let in_stream = request.into_inner();
|
||||
|
||||
start_signal_stream(self.sender.clone(), in_stream, |state| {
|
||||
&mut state.signal_state.output_resize
|
||||
&mut state.pinnacle.signal_state.output_resize
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ impl signal_service_server::SignalService for SignalService {
|
|||
let in_stream = request.into_inner();
|
||||
|
||||
start_signal_stream(self.sender.clone(), in_stream, |state| {
|
||||
&mut state.signal_state.output_move
|
||||
&mut state.pinnacle.signal_state.output_move
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ impl signal_service_server::SignalService for SignalService {
|
|||
let in_stream = request.into_inner();
|
||||
|
||||
start_signal_stream(self.sender.clone(), in_stream, |state| {
|
||||
&mut state.signal_state.window_pointer_enter
|
||||
&mut state.pinnacle.signal_state.window_pointer_enter
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ impl signal_service_server::SignalService for SignalService {
|
|||
let in_stream = request.into_inner();
|
||||
|
||||
start_signal_stream(self.sender.clone(), in_stream, |state| {
|
||||
&mut state.signal_state.window_pointer_leave
|
||||
&mut state.pinnacle.signal_state.window_pointer_leave
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ impl signal_service_server::SignalService for SignalService {
|
|||
let in_stream = request.into_inner();
|
||||
|
||||
start_signal_stream(self.sender.clone(), in_stream, |state| {
|
||||
&mut state.signal_state.tag_active
|
||||
&mut state.pinnacle.signal_state.tag_active
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,11 @@ impl window_service_server::WindowService for WindowService {
|
|||
let Some(window) = window_id.window(state) else { return };
|
||||
|
||||
// TODO: with no x or y, defaults unmapped windows to 0, 0
|
||||
let mut window_loc = state.space.element_location(&window).unwrap_or_default();
|
||||
let mut window_loc = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_location(&window)
|
||||
.unwrap_or_default();
|
||||
window_loc.x = x.unwrap_or(window_loc.x);
|
||||
window_loc.y = y.unwrap_or(window_loc.y);
|
||||
|
||||
|
@ -110,7 +114,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
}
|
||||
});
|
||||
|
||||
for output in state.space.outputs_for_element(&window) {
|
||||
for output in state.pinnacle.space.outputs_for_element(&window) {
|
||||
state.request_layout(&output);
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
|
@ -293,7 +297,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
return;
|
||||
};
|
||||
|
||||
for win in state.space.elements() {
|
||||
for win in state.pinnacle.space.elements() {
|
||||
win.set_activate(false);
|
||||
}
|
||||
|
||||
|
@ -301,8 +305,8 @@ impl window_service_server::WindowService for WindowService {
|
|||
SetOrToggle::Set => {
|
||||
window.set_activate(true);
|
||||
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
|
||||
state.output_focus_stack.set_focus(output.clone());
|
||||
if let Some(keyboard) = state.seat.get_keyboard() {
|
||||
state.pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
if let Some(keyboard) = state.pinnacle.seat.get_keyboard() {
|
||||
keyboard.set_focus(
|
||||
state,
|
||||
Some(KeyboardFocusTarget::Window(window)),
|
||||
|
@ -313,7 +317,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
SetOrToggle::Unset => {
|
||||
if state.focused_window(&output) == Some(window) {
|
||||
output.with_state_mut(|state| state.focus_stack.unset_focus());
|
||||
if let Some(keyboard) = state.seat.get_keyboard() {
|
||||
if let Some(keyboard) = state.pinnacle.seat.get_keyboard() {
|
||||
keyboard.set_focus(state, None, SERIAL_COUNTER.next_serial());
|
||||
}
|
||||
}
|
||||
|
@ -321,14 +325,14 @@ impl window_service_server::WindowService for WindowService {
|
|||
SetOrToggle::Toggle => {
|
||||
if state.focused_window(&output).as_ref() == Some(&window) {
|
||||
output.with_state_mut(|state| state.focus_stack.unset_focus());
|
||||
if let Some(keyboard) = state.seat.get_keyboard() {
|
||||
if let Some(keyboard) = state.pinnacle.seat.get_keyboard() {
|
||||
keyboard.set_focus(state, None, SERIAL_COUNTER.next_serial());
|
||||
}
|
||||
} else {
|
||||
window.set_activate(true);
|
||||
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
|
||||
state.output_focus_stack.set_focus(output.clone());
|
||||
if let Some(keyboard) = state.seat.get_keyboard() {
|
||||
state.pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
if let Some(keyboard) = state.pinnacle.seat.get_keyboard() {
|
||||
keyboard.set_focus(
|
||||
state,
|
||||
Some(KeyboardFocusTarget::Window(window)),
|
||||
|
@ -340,7 +344,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
SetOrToggle::Unspecified => unreachable!(),
|
||||
}
|
||||
|
||||
for window in state.space.elements() {
|
||||
for window in state.pinnacle.space.elements() {
|
||||
if let Some(toplevel) = window.toplevel() {
|
||||
toplevel.send_configure();
|
||||
}
|
||||
|
@ -461,7 +465,11 @@ impl window_service_server::WindowService for WindowService {
|
|||
.ok_or_else(|| Status::invalid_argument("no button specified"))?;
|
||||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
let Some(pointer_location) = state.seat.get_pointer().map(|ptr| ptr.current_location())
|
||||
let Some(pointer_location) = state
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_pointer()
|
||||
.map(|ptr| ptr.current_location())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
@ -476,7 +484,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
let Some(wl_surf) = window.wl_surface() else {
|
||||
return;
|
||||
};
|
||||
let seat = state.seat.clone();
|
||||
let seat = state.pinnacle.seat.clone();
|
||||
|
||||
crate::grab::move_grab::move_request_server(
|
||||
state,
|
||||
|
@ -500,7 +508,11 @@ impl window_service_server::WindowService for WindowService {
|
|||
.ok_or_else(|| Status::invalid_argument("no button specified"))?;
|
||||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
let Some(pointer_loc) = state.seat.get_pointer().map(|ptr| ptr.current_location())
|
||||
let Some(pointer_loc) = state
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_pointer()
|
||||
.map(|ptr| ptr.current_location())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
@ -557,7 +569,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
crate::grab::resize_grab::resize_request_server(
|
||||
state,
|
||||
&wl_surf,
|
||||
&state.seat.clone(),
|
||||
&state.pinnacle.seat.clone(),
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
edges.into(),
|
||||
button,
|
||||
|
@ -572,6 +584,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
) -> Result<Response<window::v0alpha1::GetResponse>, Status> {
|
||||
run_unary(&self.sender, move |state| {
|
||||
let window_ids = state
|
||||
.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.map(|win| win.with_state(|state| state.id.0))
|
||||
|
@ -603,12 +616,12 @@ impl window_service_server::WindowService for WindowService {
|
|||
|
||||
let x = window
|
||||
.as_ref()
|
||||
.and_then(|win| state.space.element_location(win))
|
||||
.and_then(|win| state.pinnacle.space.element_location(win))
|
||||
.map(|loc| loc.x);
|
||||
|
||||
let y = window
|
||||
.as_ref()
|
||||
.and_then(|win| state.space.element_location(win))
|
||||
.and_then(|win| state.pinnacle.space.element_location(win))
|
||||
.map(|loc| loc.y);
|
||||
|
||||
let geometry = if width.is_none() && height.is_none() && x.is_none() && y.is_none() {
|
||||
|
@ -691,7 +704,7 @@ impl window_service_server::WindowService for WindowService {
|
|||
.into();
|
||||
|
||||
run_unary_no_response(&self.sender, move |state| {
|
||||
state.config.window_rules.push((cond, rule));
|
||||
state.pinnacle.config.window_rules.push((cond, rule));
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -108,16 +108,19 @@ pub fn setup_dummy(
|
|||
config_dir,
|
||||
)?;
|
||||
|
||||
state.output_focus_stack.set_focus(output.clone());
|
||||
state.pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
|
||||
let dummy = state.backend.dummy_mut();
|
||||
|
||||
state.shm_state.update_formats(dummy.renderer.shm_formats());
|
||||
state
|
||||
.pinnacle
|
||||
.shm_state
|
||||
.update_formats(dummy.renderer.shm_formats());
|
||||
|
||||
state.space.map_output(&output, (0, 0));
|
||||
state.pinnacle.space.map_output(&output, (0, 0));
|
||||
|
||||
if let Err(err) = state.xwayland.start(
|
||||
state.loop_handle.clone(),
|
||||
if let Err(err) = state.pinnacle.xwayland.start(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
None,
|
||||
std::iter::empty::<(OsString, OsString)>(),
|
||||
true,
|
||||
|
@ -149,11 +152,11 @@ impl State {
|
|||
|
||||
output.set_preferred(mode);
|
||||
|
||||
output.create_global::<State>(&self.display_handle);
|
||||
output.create_global::<State>(&self.pinnacle.display_handle);
|
||||
|
||||
self.space.map_output(&output, (0, 0));
|
||||
self.pinnacle.space.map_output(&output, (0, 0));
|
||||
|
||||
self.signal_state.output_connect.signal(|buf| {
|
||||
self.pinnacle.signal_state.output_connect.signal(|buf| {
|
||||
buf.push_back(OutputConnectResponse {
|
||||
output_name: Some(output.name()),
|
||||
});
|
||||
|
@ -161,12 +164,15 @@ impl State {
|
|||
}
|
||||
|
||||
pub fn remove_output(&mut self, output: &Output) {
|
||||
self.space.unmap_output(output);
|
||||
self.pinnacle.space.unmap_output(output);
|
||||
|
||||
self.signal_state.output_disconnect.signal(|buffer| {
|
||||
buffer.push_back(OutputDisconnectResponse {
|
||||
output_name: Some(output.name()),
|
||||
})
|
||||
});
|
||||
self.pinnacle
|
||||
.signal_state
|
||||
.output_disconnect
|
||||
.signal(|buffer| {
|
||||
buffer.push_back(OutputDisconnectResponse {
|
||||
output_name: Some(output.name()),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -432,7 +432,7 @@ pub fn setup_udev(
|
|||
udev.session.clone().into(),
|
||||
);
|
||||
libinput_context
|
||||
.udev_assign_seat(state.seat.name())
|
||||
.udev_assign_seat(state.pinnacle.seat.name())
|
||||
.expect("failed to assign seat to libinput");
|
||||
let libinput_backend = LibinputInputBackend::new(libinput_context.clone());
|
||||
|
||||
|
@ -576,7 +576,7 @@ pub fn setup_udev(
|
|||
}
|
||||
}
|
||||
|
||||
for output in state.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in state.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ pub fn setup_udev(
|
|||
})
|
||||
.expect("failed to insert libinput notifier into event loop");
|
||||
|
||||
state.shm_state.update_formats(
|
||||
state.pinnacle.shm_state.update_formats(
|
||||
udev.gpu_manager
|
||||
.single_renderer(&primary_gpu)?
|
||||
.shm_formats(),
|
||||
|
@ -676,8 +676,8 @@ pub fn setup_udev(
|
|||
});
|
||||
});
|
||||
|
||||
if let Err(err) = state.xwayland.start(
|
||||
state.loop_handle.clone(),
|
||||
if let Err(err) = state.pinnacle.xwayland.start(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
None,
|
||||
std::iter::empty::<(OsString, OsString)>(),
|
||||
true,
|
||||
|
@ -903,6 +903,7 @@ impl State {
|
|||
let gbm = GbmDevice::new(fd).map_err(DeviceAddError::GbmDevice)?;
|
||||
|
||||
let registration_token = self
|
||||
.pinnacle
|
||||
.loop_handle
|
||||
.insert_source(notifier, move |event, metadata, state| match event {
|
||||
DrmEvent::VBlank(crtc) => {
|
||||
|
@ -1011,7 +1012,7 @@ impl State {
|
|||
|
||||
let (phys_w, phys_h) = connector.size().unwrap_or((0, 0));
|
||||
|
||||
if self.space.outputs().any(|op| {
|
||||
if self.pinnacle.space.outputs().any(|op| {
|
||||
op.user_data()
|
||||
.get::<UdevOutputData>()
|
||||
.is_some_and(|op_id| op_id.crtc == crtc)
|
||||
|
@ -1034,10 +1035,10 @@ impl State {
|
|||
|
||||
output.set_preferred(wl_mode);
|
||||
|
||||
self.output_focus_stack.set_focus(output.clone());
|
||||
self.pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
|
||||
let x = self.space.outputs().fold(0, |acc, o| {
|
||||
let Some(geo) = self.space.output_geometry(o) else {
|
||||
let x = self.pinnacle.space.outputs().fold(0, |acc, o| {
|
||||
let Some(geo) = self.pinnacle.space.output_geometry(o) else {
|
||||
unreachable!()
|
||||
};
|
||||
acc + geo.size.w
|
||||
|
@ -1116,6 +1117,7 @@ impl State {
|
|||
// In this case, restore its tags and location.
|
||||
// TODO: instead of checking the connector, check the monitor's edid info instead
|
||||
if let Some(saved_state) = self
|
||||
.pinnacle
|
||||
.config
|
||||
.connector_saved_states
|
||||
.get(&OutputName(output.name()))
|
||||
|
@ -1124,7 +1126,7 @@ impl State {
|
|||
output.with_state_mut(|state| state.tags = tags.clone());
|
||||
self.change_output_state(&output, None, None, *scale, Some(*loc));
|
||||
} else {
|
||||
self.signal_state.output_connect.signal(|buffer| {
|
||||
self.pinnacle.signal_state.output_connect.signal(|buffer| {
|
||||
buffer.push_back(OutputConnectResponse {
|
||||
output_name: Some(output.name()),
|
||||
})
|
||||
|
@ -1152,6 +1154,7 @@ impl State {
|
|||
device.surfaces.remove(&crtc);
|
||||
|
||||
let output = self
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.find(|o| {
|
||||
|
@ -1164,7 +1167,7 @@ impl State {
|
|||
|
||||
if let Some(output) = output {
|
||||
// Save this output's state. It will be restored if the monitor gets replugged.
|
||||
self.config.connector_saved_states.insert(
|
||||
self.pinnacle.config.connector_saved_states.insert(
|
||||
OutputName(output.name()),
|
||||
ConnectorSavedState {
|
||||
loc: output.current_location(),
|
||||
|
@ -1172,14 +1175,19 @@ impl State {
|
|||
scale: Some(output.current_scale()),
|
||||
},
|
||||
);
|
||||
self.space.unmap_output(&output);
|
||||
self.gamma_control_manager_state.output_removed(&output);
|
||||
self.pinnacle.space.unmap_output(&output);
|
||||
self.pinnacle
|
||||
.gamma_control_manager_state
|
||||
.output_removed(&output);
|
||||
|
||||
self.signal_state.output_disconnect.signal(|buffer| {
|
||||
buffer.push_back(OutputDisconnectResponse {
|
||||
output_name: Some(output.name()),
|
||||
})
|
||||
});
|
||||
self.pinnacle
|
||||
.signal_state
|
||||
.output_disconnect
|
||||
.signal(|buffer| {
|
||||
buffer.push_back(OutputDisconnectResponse {
|
||||
output_name: Some(output.name()),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1241,7 +1249,9 @@ impl State {
|
|||
.as_mut()
|
||||
.remove_node(&backend_data.render_node);
|
||||
|
||||
self.loop_handle.remove(backend_data.registration_token);
|
||||
self.pinnacle
|
||||
.loop_handle
|
||||
.remove(backend_data.registration_token);
|
||||
|
||||
tracing::debug!("Dropping device");
|
||||
}
|
||||
|
@ -1264,7 +1274,7 @@ impl State {
|
|||
return;
|
||||
};
|
||||
|
||||
let output = if let Some(output) = self.space.outputs().find(|o| {
|
||||
let output = if let Some(output) = self.pinnacle.space.outputs().find(|o| {
|
||||
let udev_op_data = o.user_data().get::<UdevOutputData>();
|
||||
udev_op_data
|
||||
.is_some_and(|data| data.device_id == surface.device_id && data.crtc == crtc)
|
||||
|
@ -1299,7 +1309,10 @@ impl State {
|
|||
| wp_presentation_feedback::Kind::HwCompletion,
|
||||
)
|
||||
} else {
|
||||
(self.clock.now(), wp_presentation_feedback::Kind::Vsync)
|
||||
(
|
||||
self.pinnacle.clock.now(),
|
||||
wp_presentation_feedback::Kind::Vsync,
|
||||
)
|
||||
};
|
||||
|
||||
feedback.presented(
|
||||
|
@ -1330,10 +1343,13 @@ impl State {
|
|||
if dirty {
|
||||
self.schedule_render(&output);
|
||||
} else {
|
||||
for window in self.windows.iter() {
|
||||
window.send_frame(&output, self.clock.now(), Some(Duration::ZERO), |_, _| {
|
||||
Some(output.clone())
|
||||
});
|
||||
for window in self.pinnacle.windows.iter() {
|
||||
window.send_frame(
|
||||
&output,
|
||||
self.pinnacle.clock.now(),
|
||||
Some(Duration::ZERO),
|
||||
|_, _| Some(output.clone()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1353,7 +1369,7 @@ impl State {
|
|||
let frame = udev.pointer_image.get_image(
|
||||
1,
|
||||
// output.current_scale().integer_scale() as u32,
|
||||
self.clock.now().into(),
|
||||
self.pinnacle.clock.now().into(),
|
||||
);
|
||||
|
||||
let render_node = surface.render_node;
|
||||
|
@ -1398,9 +1414,10 @@ impl State {
|
|||
texture
|
||||
});
|
||||
|
||||
let windows = self.space.elements().cloned().collect::<Vec<_>>();
|
||||
let windows = self.pinnacle.space.elements().cloned().collect::<Vec<_>>();
|
||||
|
||||
let pointer_location = self
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_pointer()
|
||||
.map(|ptr| ptr.current_location())
|
||||
|
@ -1411,21 +1428,22 @@ impl State {
|
|||
|
||||
// draw the cursor as relevant and
|
||||
// reset the cursor if the surface is no longer alive
|
||||
if let CursorImageStatus::Surface(surface) = &self.cursor_status {
|
||||
if let CursorImageStatus::Surface(surface) = &self.pinnacle.cursor_status {
|
||||
if !surface.alive() {
|
||||
self.cursor_status = CursorImageStatus::default_named();
|
||||
self.pinnacle.cursor_status = CursorImageStatus::default_named();
|
||||
} else {
|
||||
send_frames_surface_tree(
|
||||
surface,
|
||||
output,
|
||||
self.clock.now(),
|
||||
self.pinnacle.clock.now(),
|
||||
Some(Duration::ZERO),
|
||||
|_, _| None,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
udev.pointer_element.set_status(self.cursor_status.clone());
|
||||
udev.pointer_element
|
||||
.set_status(self.pinnacle.cursor_status.clone());
|
||||
|
||||
let pending_screencopy_with_cursor =
|
||||
output.with_state(|state| state.screencopy.as_ref().map(|sc| sc.overlay_cursor()));
|
||||
|
@ -1449,10 +1467,10 @@ impl State {
|
|||
let pointer_render_elements = pointer_render_elements(
|
||||
output,
|
||||
&mut renderer,
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
pointer_location,
|
||||
&mut self.cursor_status,
|
||||
self.dnd_icon.as_ref(),
|
||||
&mut self.pinnacle.cursor_status,
|
||||
self.pinnacle.dnd_icon.as_ref(),
|
||||
&udev.pointer_element,
|
||||
);
|
||||
udev.pointer_element.set_element_kind(element::Kind::Cursor);
|
||||
|
@ -1463,10 +1481,10 @@ impl State {
|
|||
let pointer_render_elements = pointer_render_elements(
|
||||
output,
|
||||
&mut renderer,
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
pointer_location,
|
||||
&mut self.cursor_status,
|
||||
self.dnd_icon.as_ref(),
|
||||
&mut self.pinnacle.cursor_status,
|
||||
self.pinnacle.dnd_icon.as_ref(),
|
||||
&udev.pointer_element,
|
||||
);
|
||||
output_render_elements.extend(pointer_render_elements);
|
||||
|
@ -1476,7 +1494,7 @@ impl State {
|
|||
output_render_elements.extend(crate::render::output_render_elements(
|
||||
output,
|
||||
&mut renderer,
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
&windows,
|
||||
));
|
||||
|
||||
|
@ -1499,13 +1517,13 @@ impl State {
|
|||
output,
|
||||
surface,
|
||||
&render_frame_result,
|
||||
&self.loop_handle,
|
||||
&self.pinnacle.loop_handle,
|
||||
);
|
||||
|
||||
super::post_repaint(
|
||||
output,
|
||||
&render_frame_result.states,
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
surface
|
||||
.dmabuf_feedback
|
||||
.as_ref()
|
||||
|
@ -1513,15 +1531,18 @@ impl State {
|
|||
render_feedback: &feedback.render_feedback,
|
||||
scanout_feedback: &feedback.scanout_feedback,
|
||||
}),
|
||||
Duration::from(self.clock.now()),
|
||||
&self.cursor_status,
|
||||
Duration::from(self.pinnacle.clock.now()),
|
||||
&self.pinnacle.cursor_status,
|
||||
);
|
||||
|
||||
let rendered = !render_frame_result.is_empty;
|
||||
|
||||
if rendered {
|
||||
let output_presentation_feedback =
|
||||
take_presentation_feedback(output, &self.space, &render_frame_result.states);
|
||||
let output_presentation_feedback = take_presentation_feedback(
|
||||
output,
|
||||
&self.pinnacle.space,
|
||||
&render_frame_result.states,
|
||||
);
|
||||
|
||||
surface
|
||||
.compositor
|
||||
|
|
|
@ -190,18 +190,19 @@ pub fn setup_winit(
|
|||
// wl-mirror segfaults if it gets a wl-output global before the xdg output manager global
|
||||
output.create_global::<State>(&display_handle);
|
||||
|
||||
state.output_focus_stack.set_focus(output.clone());
|
||||
state.pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
|
||||
let winit = state.backend.winit_mut();
|
||||
|
||||
state
|
||||
.pinnacle
|
||||
.shm_state
|
||||
.update_formats(winit.backend.renderer().shm_formats());
|
||||
|
||||
state.space.map_output(&output, (0, 0));
|
||||
state.pinnacle.space.map_output(&output, (0, 0));
|
||||
|
||||
if let Err(err) = state.xwayland.start(
|
||||
state.loop_handle.clone(),
|
||||
if let Err(err) = state.pinnacle.xwayland.start(
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
None,
|
||||
std::iter::empty::<(OsString, OsString)>(),
|
||||
true,
|
||||
|
@ -210,49 +211,49 @@ pub fn setup_winit(
|
|||
error!("Failed to start XWayland: {err}");
|
||||
}
|
||||
|
||||
let insert_ret =
|
||||
state
|
||||
.loop_handle
|
||||
.insert_source(Timer::immediate(), move |_instant, _metadata, state| {
|
||||
let status = winit_evt_loop.dispatch_new_events(|event| match event {
|
||||
WinitEvent::Resized { size, scale_factor } => {
|
||||
let mode = smithay::output::Mode {
|
||||
size,
|
||||
refresh: 144_000,
|
||||
};
|
||||
state.change_output_state(
|
||||
&output,
|
||||
Some(mode),
|
||||
None,
|
||||
Some(Scale::Fractional(scale_factor)),
|
||||
None,
|
||||
);
|
||||
state.request_layout(&output);
|
||||
let insert_ret = state.pinnacle.loop_handle.insert_source(
|
||||
Timer::immediate(),
|
||||
move |_instant, _metadata, state| {
|
||||
let status = winit_evt_loop.dispatch_new_events(|event| match event {
|
||||
WinitEvent::Resized { size, scale_factor } => {
|
||||
let mode = smithay::output::Mode {
|
||||
size,
|
||||
refresh: 144_000,
|
||||
};
|
||||
state.change_output_state(
|
||||
&output,
|
||||
Some(mode),
|
||||
None,
|
||||
Some(Scale::Fractional(scale_factor)),
|
||||
None,
|
||||
);
|
||||
state.request_layout(&output);
|
||||
}
|
||||
WinitEvent::Focus(focused) => {
|
||||
if focused {
|
||||
state.backend.winit_mut().reset_buffers(&output);
|
||||
}
|
||||
WinitEvent::Focus(focused) => {
|
||||
if focused {
|
||||
state.backend.winit_mut().reset_buffers(&output);
|
||||
}
|
||||
}
|
||||
WinitEvent::Input(input_evt) => {
|
||||
state.process_input_event(input_evt);
|
||||
}
|
||||
WinitEvent::Redraw => {
|
||||
state.render_winit_window(&output);
|
||||
}
|
||||
WinitEvent::CloseRequested => {
|
||||
state.shutdown();
|
||||
}
|
||||
});
|
||||
|
||||
if let PumpStatus::Exit(_) = status {
|
||||
}
|
||||
WinitEvent::Input(input_evt) => {
|
||||
state.process_input_event(input_evt);
|
||||
}
|
||||
WinitEvent::Redraw => {
|
||||
state.render_winit_window(&output);
|
||||
}
|
||||
WinitEvent::CloseRequested => {
|
||||
state.shutdown();
|
||||
}
|
||||
|
||||
state.render_winit_window(&output);
|
||||
|
||||
TimeoutAction::ToDuration(Duration::from_micros(((1.0 / 144.0) * 1000000.0) as u64))
|
||||
});
|
||||
|
||||
if let PumpStatus::Exit(_) = status {
|
||||
state.shutdown();
|
||||
}
|
||||
|
||||
state.render_winit_window(&output);
|
||||
|
||||
TimeoutAction::ToDuration(Duration::from_micros(((1.0 / 144.0) * 1000000.0) as u64))
|
||||
},
|
||||
);
|
||||
if let Err(err) = insert_ret {
|
||||
anyhow::bail!("Failed to insert winit events into event loop: {err}");
|
||||
}
|
||||
|
@ -267,21 +268,21 @@ impl State {
|
|||
let full_redraw = &mut winit.full_redraw;
|
||||
*full_redraw = full_redraw.saturating_sub(1);
|
||||
|
||||
if let CursorImageStatus::Surface(surface) = &self.cursor_status {
|
||||
if let CursorImageStatus::Surface(surface) = &self.pinnacle.cursor_status {
|
||||
if !surface.alive() {
|
||||
self.cursor_status = CursorImageStatus::default_named();
|
||||
self.pinnacle.cursor_status = CursorImageStatus::default_named();
|
||||
}
|
||||
}
|
||||
|
||||
let cursor_visible = !matches!(self.cursor_status, CursorImageStatus::Surface(_));
|
||||
let cursor_visible = !matches!(self.pinnacle.cursor_status, CursorImageStatus::Surface(_));
|
||||
|
||||
let mut pointer_element = PointerElement::<GlesTexture>::new();
|
||||
|
||||
pointer_element.set_status(self.cursor_status.clone());
|
||||
pointer_element.set_status(self.pinnacle.cursor_status.clone());
|
||||
|
||||
// The z-index of these is determined by `state.fixup_z_layering()`, which is called at the end
|
||||
// of every event loop cycle
|
||||
let windows = self.space.elements().cloned().collect::<Vec<_>>();
|
||||
let windows = self.pinnacle.space.elements().cloned().collect::<Vec<_>>();
|
||||
|
||||
let mut output_render_elements = Vec::new();
|
||||
|
||||
|
@ -299,6 +300,7 @@ impl State {
|
|||
// but it shouldn't meaningfully affect anything.
|
||||
if !pending_screencopy_without_cursor {
|
||||
let pointer_location = self
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_pointer()
|
||||
.map(|ptr| ptr.current_location())
|
||||
|
@ -307,10 +309,10 @@ impl State {
|
|||
let pointer_render_elements = pointer_render_elements(
|
||||
output,
|
||||
winit.backend.renderer(),
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
pointer_location,
|
||||
&mut self.cursor_status,
|
||||
self.dnd_icon.as_ref(),
|
||||
&mut self.pinnacle.cursor_status,
|
||||
self.pinnacle.dnd_icon.as_ref(),
|
||||
&pointer_element,
|
||||
);
|
||||
output_render_elements.extend(pointer_render_elements);
|
||||
|
@ -319,7 +321,7 @@ impl State {
|
|||
output_render_elements.extend(crate::render::output_render_elements(
|
||||
output,
|
||||
winit.backend.renderer(),
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
&windows,
|
||||
));
|
||||
|
||||
|
@ -347,7 +349,7 @@ impl State {
|
|||
&mut winit.backend,
|
||||
output,
|
||||
&render_output_result,
|
||||
&self.loop_handle,
|
||||
&self.pinnacle.loop_handle,
|
||||
);
|
||||
|
||||
let has_rendered = render_output_result.damage.is_some();
|
||||
|
@ -359,21 +361,21 @@ impl State {
|
|||
|
||||
winit.backend.window().set_cursor_visible(cursor_visible);
|
||||
|
||||
let time = self.clock.now();
|
||||
let time = self.pinnacle.clock.now();
|
||||
|
||||
super::post_repaint(
|
||||
output,
|
||||
&render_output_result.states,
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
None,
|
||||
time.into(),
|
||||
&self.cursor_status,
|
||||
&self.pinnacle.cursor_status,
|
||||
);
|
||||
|
||||
if has_rendered {
|
||||
let mut output_presentation_feedback = take_presentation_feedback(
|
||||
output,
|
||||
&self.space,
|
||||
&self.pinnacle.space,
|
||||
&render_output_result.states,
|
||||
);
|
||||
output_presentation_feedback.presented(
|
||||
|
|
|
@ -80,11 +80,11 @@ pub fn setup_wlcs_dummy() -> anyhow::Result<(State, EventLoop<'static, State>)>
|
|||
None,
|
||||
)?;
|
||||
|
||||
state.output_focus_stack.set_focus(output.clone());
|
||||
state.pinnacle.output_focus_stack.set_focus(output.clone());
|
||||
|
||||
state.shm_state.update_formats(shm_formats);
|
||||
state.pinnacle.shm_state.update_formats(shm_formats);
|
||||
|
||||
state.space.map_output(&output, (0, 0));
|
||||
state.pinnacle.space.map_output(&output, (0, 0));
|
||||
|
||||
Ok((state, event_loop))
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ impl State {
|
|||
{
|
||||
// Clear state
|
||||
debug!("Clearing tags");
|
||||
for output in self.space.outputs() {
|
||||
for output in self.pinnacle.space.outputs() {
|
||||
output.with_state_mut(|state| state.tags.clear());
|
||||
}
|
||||
|
||||
|
@ -104,22 +104,23 @@ impl State {
|
|||
|
||||
debug!("Clearing input state");
|
||||
|
||||
self.input_state.clear();
|
||||
self.pinnacle.input_state.clear();
|
||||
|
||||
self.config.clear(&self.loop_handle);
|
||||
self.pinnacle.config.clear(&self.pinnacle.loop_handle);
|
||||
|
||||
self.signal_state.clear();
|
||||
self.pinnacle.signal_state.clear();
|
||||
|
||||
self.input_state.reload_keybind = None;
|
||||
self.input_state.kill_keybind = None;
|
||||
self.pinnacle.input_state.reload_keybind = None;
|
||||
self.pinnacle.input_state.kill_keybind = None;
|
||||
|
||||
if self.grpc_server_join_handle.is_none() {
|
||||
if self.pinnacle.grpc_server_join_handle.is_none() {
|
||||
self.start_grpc_server(socket_dir)?;
|
||||
}
|
||||
|
||||
let (pinger, ping_source) = calloop::ping::make_ping()?;
|
||||
|
||||
let token = self
|
||||
.pinnacle
|
||||
.loop_handle
|
||||
.insert_source(ping_source, move |_, _, _state| {})?;
|
||||
|
||||
|
@ -128,7 +129,7 @@ impl State {
|
|||
pinger.ping();
|
||||
});
|
||||
|
||||
self.config.config_reload_on_crash_token = Some(token);
|
||||
self.pinnacle.config.config_reload_on_crash_token = Some(token);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ impl State {
|
|||
// Clear state
|
||||
|
||||
debug!("Clearing tags");
|
||||
for output in self.space.outputs() {
|
||||
for output in self.pinnacle.space.outputs() {
|
||||
output.with_state_mut(|state| state.tags.clear());
|
||||
}
|
||||
|
||||
|
@ -284,11 +284,11 @@ impl State {
|
|||
|
||||
debug!("Clearing input state");
|
||||
|
||||
self.input_state.clear();
|
||||
self.pinnacle.input_state.clear();
|
||||
|
||||
self.config.clear(&self.loop_handle);
|
||||
self.pinnacle.config.clear(&self.pinnacle.loop_handle);
|
||||
|
||||
self.signal_state.clear();
|
||||
self.pinnacle.signal_state.clear();
|
||||
|
||||
let config_dir_clone = config_dir.as_ref().map(|dir| dir.as_ref().to_path_buf());
|
||||
let load_default_config = |state: &mut State, reason: &str| {
|
||||
|
@ -304,7 +304,7 @@ impl State {
|
|||
};
|
||||
|
||||
// If `--no-config` was set, still load the keybinds from the default metaconfig
|
||||
if self.config.no_config {
|
||||
if self.pinnacle.config.no_config {
|
||||
config_dir = None;
|
||||
}
|
||||
|
||||
|
@ -328,17 +328,17 @@ impl State {
|
|||
let reload_keybind = (reload_mask, Keysym::from(reload_keybind.key as u32));
|
||||
let kill_keybind = (kill_mask, Keysym::from(kill_keybind.key as u32));
|
||||
|
||||
self.input_state.reload_keybind = Some(reload_keybind);
|
||||
self.input_state.kill_keybind = Some(kill_keybind);
|
||||
self.pinnacle.input_state.reload_keybind = Some(reload_keybind);
|
||||
self.pinnacle.input_state.kill_keybind = Some(kill_keybind);
|
||||
|
||||
if self.config.no_config {
|
||||
if self.pinnacle.config.no_config {
|
||||
info!("`--no-config` was set, not spawning config");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Because the grpc server is implemented to only start once,
|
||||
// any updates to `socket_dir` won't be applied until restart.
|
||||
if self.grpc_server_join_handle.is_none() {
|
||||
if self.pinnacle.grpc_server_join_handle.is_none() {
|
||||
// If a socket is provided in the metaconfig, use it.
|
||||
let socket_dir = if let Some(socket_dir) = &metaconfig.socket_dir {
|
||||
let Some(config_dir) = &config_dir else {
|
||||
|
@ -356,7 +356,8 @@ impl State {
|
|||
socket_dir
|
||||
} else {
|
||||
// Otherwise, use $XDG_RUNTIME_DIR. If that doesn't exist, use /tmp.
|
||||
self.xdg_base_dirs
|
||||
self.pinnacle
|
||||
.xdg_base_dirs
|
||||
.get_runtime_directory()
|
||||
.cloned()
|
||||
.unwrap_or(PathBuf::from(DEFAULT_SOCKET_DIR))
|
||||
|
@ -448,30 +449,32 @@ impl State {
|
|||
|
||||
let (pinger, ping_source) = calloop::ping::make_ping()?;
|
||||
|
||||
let token = self
|
||||
.loop_handle
|
||||
.insert_source(ping_source, move |_, _, state| {
|
||||
error!("Config crashed! Falling back to default config");
|
||||
state
|
||||
.start_config(None::<PathBuf>)
|
||||
.expect("failed to start default config");
|
||||
})?;
|
||||
let token =
|
||||
self.pinnacle
|
||||
.loop_handle
|
||||
.insert_source(ping_source, move |_, _, state| {
|
||||
error!("Config crashed! Falling back to default config");
|
||||
state
|
||||
.start_config(None::<PathBuf>)
|
||||
.expect("failed to start default config");
|
||||
})?;
|
||||
|
||||
self.config.config_join_handle = Some(tokio::spawn(async move {
|
||||
self.pinnacle.config.config_join_handle = Some(tokio::spawn(async move {
|
||||
let _ = child.wait().await;
|
||||
pinger.ping();
|
||||
}));
|
||||
|
||||
self.config.config_reload_on_crash_token = Some(token);
|
||||
self.pinnacle.config.config_reload_on_crash_token = Some(token);
|
||||
}
|
||||
None => {
|
||||
let (pinger, ping_source) = calloop::ping::make_ping()?;
|
||||
|
||||
let token = self
|
||||
.loop_handle
|
||||
.insert_source(ping_source, move |_, _, _state| {
|
||||
panic!("builtin rust config crashed; this is a bug");
|
||||
})?;
|
||||
let token =
|
||||
self.pinnacle
|
||||
.loop_handle
|
||||
.insert_source(ping_source, move |_, _, _state| {
|
||||
panic!("builtin rust config crashed; this is a bug");
|
||||
})?;
|
||||
|
||||
std::thread::spawn(move || {
|
||||
info!("Starting builtin Rust config");
|
||||
|
@ -479,7 +482,7 @@ impl State {
|
|||
pinger.ping();
|
||||
});
|
||||
|
||||
self.config.config_reload_on_crash_token = Some(token);
|
||||
self.pinnacle.config.config_reload_on_crash_token = Some(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,10 +490,12 @@ impl State {
|
|||
}
|
||||
|
||||
pub fn start_grpc_server(&mut self, socket_dir: &Path) -> anyhow::Result<()> {
|
||||
self.system_processes
|
||||
self.pinnacle
|
||||
.system_processes
|
||||
.refresh_processes_specifics(ProcessRefreshKind::new());
|
||||
|
||||
let multiple_instances = self
|
||||
.pinnacle
|
||||
.system_processes
|
||||
.processes_by_exact_name("pinnacle")
|
||||
.filter(|proc| proc.thread_kind().is_none())
|
||||
|
@ -539,13 +544,14 @@ impl State {
|
|||
|
||||
std::env::set_var(
|
||||
"PINNACLE_PROTO_DIR",
|
||||
self.xdg_base_dirs.get_data_file("protobuf"),
|
||||
self.pinnacle.xdg_base_dirs.get_data_file("protobuf"),
|
||||
);
|
||||
|
||||
let (grpc_sender, grpc_receiver) =
|
||||
calloop::channel::channel::<Box<dyn FnOnce(&mut Self) + Send>>();
|
||||
|
||||
self.loop_handle
|
||||
self.pinnacle
|
||||
.loop_handle
|
||||
.insert_source(grpc_receiver, |msg, _, state| match msg {
|
||||
Event::Msg(f) => f(state),
|
||||
Event::Closed => error!("grpc receiver was closed"),
|
||||
|
@ -583,9 +589,9 @@ impl State {
|
|||
.add_service(LayoutServiceServer::new(layout_service))
|
||||
.add_service(RenderServiceServer::new(render_service));
|
||||
|
||||
match self.xdisplay.as_ref() {
|
||||
match self.pinnacle.xdisplay.as_ref() {
|
||||
Some(_) => {
|
||||
self.grpc_server_join_handle = Some(tokio::spawn(async move {
|
||||
self.pinnacle.grpc_server_join_handle = Some(tokio::spawn(async move {
|
||||
if let Err(err) = grpc_server.serve_with_incoming(uds_stream).await {
|
||||
error!("gRPC server error: {err}");
|
||||
}
|
||||
|
@ -595,9 +601,9 @@ impl State {
|
|||
// | fast at startup then I think there's a chance that the gRPC server
|
||||
// | could get started twice.
|
||||
None => self.schedule(
|
||||
|state| state.xdisplay.is_some(),
|
||||
|state| state.pinnacle.xdisplay.is_some(),
|
||||
move |state| {
|
||||
state.grpc_server_join_handle = Some(tokio::spawn(async move {
|
||||
state.pinnacle.grpc_server_join_handle = Some(tokio::spawn(async move {
|
||||
if let Err(err) = grpc_server.serve_with_incoming(uds_stream).await {
|
||||
error!("gRPC server error: {err}");
|
||||
}
|
||||
|
|
33
src/focus.rs
33
src/focus.rs
|
@ -47,16 +47,20 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
self.seat.get_keyboard().expect("no keyboard").set_focus(
|
||||
self,
|
||||
current_focus.map(|win| win.into()),
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
);
|
||||
self.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("no keyboard")
|
||||
.set_focus(
|
||||
self,
|
||||
current_focus.map(|win| win.into()),
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn fixup_z_layering(&mut self) {
|
||||
for win in self.z_index_stack.iter() {
|
||||
self.space.raise_element(win, false);
|
||||
for win in self.pinnacle.z_index_stack.iter() {
|
||||
self.pinnacle.space.raise_element(win, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,25 +68,26 @@ impl State {
|
|||
///
|
||||
/// This does nothing if the window is unmapped.
|
||||
pub fn raise_window(&mut self, window: WindowElement, activate: bool) {
|
||||
if self.space.elements().all(|win| win != &window) {
|
||||
if self.pinnacle.space.elements().all(|win| win != &window) {
|
||||
warn!("Tried to raise an unmapped window");
|
||||
return;
|
||||
}
|
||||
|
||||
self.space.raise_element(&window, activate);
|
||||
self.pinnacle.space.raise_element(&window, activate);
|
||||
|
||||
self.z_index_stack.retain(|win| win != &window);
|
||||
self.z_index_stack.push(window);
|
||||
self.pinnacle.z_index_stack.retain(|win| win != &window);
|
||||
self.pinnacle.z_index_stack.push(window);
|
||||
|
||||
self.fixup_xwayland_internal_z_indices();
|
||||
self.fixup_xwayland_window_layering();
|
||||
}
|
||||
|
||||
/// Get the currently focused output, or the first mapped output if there is none, or None.
|
||||
pub fn focused_output(&self) -> Option<&Output> {
|
||||
self.output_focus_stack
|
||||
self.pinnacle
|
||||
.output_focus_stack
|
||||
.stack
|
||||
.last()
|
||||
.or_else(|| self.space.outputs().next())
|
||||
.or_else(|| self.pinnacle.space.outputs().next())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ impl PointerFocusTarget {
|
|||
pub fn window_for(&self, state: &State) -> Option<WindowElement> {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface(surf) => state
|
||||
.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.find(|win| {
|
||||
|
@ -51,6 +52,7 @@ impl PointerFocusTarget {
|
|||
})
|
||||
.cloned(),
|
||||
PointerFocusTarget::X11Surface(surf) => state
|
||||
.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.find(|win| win.x11_surface() == Some(surf))
|
||||
|
@ -61,7 +63,7 @@ impl PointerFocusTarget {
|
|||
pub fn layer_for(&self, state: &State) -> Option<LayerSurface> {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface(surf) => {
|
||||
for output in state.space.outputs() {
|
||||
for output in state.pinnacle.space.outputs() {
|
||||
let map = layer_map_for_output(output);
|
||||
for layer in map.layers() {
|
||||
let mut found = false;
|
||||
|
@ -83,7 +85,7 @@ impl PointerFocusTarget {
|
|||
|
||||
pub fn popup_for(&self, state: &State) -> Option<PopupKind> {
|
||||
match self {
|
||||
PointerFocusTarget::WlSurface(surf) => state.popup_manager.find_popup(surf),
|
||||
PointerFocusTarget::WlSurface(surf) => state.pinnacle.popup_manager.find_popup(surf),
|
||||
PointerFocusTarget::X11Surface(_) => None,
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +123,8 @@ impl PointerTarget<State> for PointerFocusTarget {
|
|||
if let Some(window) = self.window_for(data) {
|
||||
let window_id = Some(window.with_state(|state| state.id.0));
|
||||
|
||||
data.signal_state
|
||||
data.pinnacle
|
||||
.signal_state
|
||||
.window_pointer_enter
|
||||
.signal(|buffer| buffer.push_back(WindowPointerEnterResponse { window_id }));
|
||||
}
|
||||
|
@ -312,7 +315,8 @@ impl PointerTarget<State> for PointerFocusTarget {
|
|||
if let Some(window) = self.window_for(data) {
|
||||
let window_id = Some(window.with_state(|state| state.id.0));
|
||||
|
||||
data.signal_state
|
||||
data.pinnacle
|
||||
.signal_state
|
||||
.window_pointer_leave
|
||||
.signal(|buffer| buffer.push_back(WindowPointerLeaveResponse { window_id }));
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ impl PointerGrab<State> for MoveSurfaceGrab {
|
|||
// INFO: can you raise OR windows or no idk
|
||||
if !surface.is_override_redirect() {
|
||||
state
|
||||
.pinnacle
|
||||
.xwm
|
||||
.as_mut()
|
||||
.expect("no xwm")
|
||||
|
@ -72,11 +73,12 @@ impl PointerGrab<State> for MoveSurfaceGrab {
|
|||
// INFO: this is being used instead of space.element_under(event.location) because that
|
||||
// | uses the bounding box, which is different from the actual geometry
|
||||
let window_under = state
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.rev()
|
||||
.find(|&win| {
|
||||
if let Some(loc) = state.space.element_location(win) {
|
||||
if let Some(loc) = state.pinnacle.space.element_location(win) {
|
||||
let size = win.geometry().size;
|
||||
let rect = Rectangle { size, loc };
|
||||
rect.contains(event.location.to_i32_round())
|
||||
|
@ -87,7 +89,7 @@ impl PointerGrab<State> for MoveSurfaceGrab {
|
|||
.cloned();
|
||||
|
||||
if let Some(window_under) = window_under {
|
||||
if state.layout_state.pending_swap {
|
||||
if state.pinnacle.layout_state.pending_swap {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -96,10 +98,12 @@ impl PointerGrab<State> for MoveSurfaceGrab {
|
|||
}
|
||||
|
||||
if state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_geometry(&self.window)
|
||||
.is_some_and(|geo| {
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_geometry(&window_under)
|
||||
.is_some_and(|geo2| geo.overlaps(geo2))
|
||||
|
@ -120,9 +124,13 @@ impl PointerGrab<State> for MoveSurfaceGrab {
|
|||
} else {
|
||||
let delta = event.location - self.start_data.location;
|
||||
let new_loc = (self.initial_window_loc.to_f64() + delta).to_i32_round();
|
||||
state.space.map_element(self.window.clone(), new_loc, true);
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.map_element(self.window.clone(), new_loc, true);
|
||||
|
||||
let size = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_geometry(&self.window)
|
||||
.expect("window wasn't mapped")
|
||||
|
@ -145,7 +153,7 @@ impl PointerGrab<State> for MoveSurfaceGrab {
|
|||
}
|
||||
}
|
||||
|
||||
let outputs = state.space.outputs_for_element(&self.window);
|
||||
let outputs = state.pinnacle.space.outputs_for_element(&self.window);
|
||||
for output in outputs {
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
|
@ -278,6 +286,7 @@ pub fn move_request_client(
|
|||
};
|
||||
|
||||
let initial_window_loc = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_location(&window)
|
||||
.expect("move request was called on an unmapped window");
|
||||
|
@ -309,6 +318,7 @@ pub fn move_request_server(
|
|||
};
|
||||
|
||||
let initial_window_loc = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_location(&window)
|
||||
.expect("move request was called on an unmapped window");
|
||||
|
|
|
@ -204,6 +204,7 @@ impl PointerGrab<State> for ResizeSurfaceGrab {
|
|||
WindowSurface::X11(surface) => {
|
||||
if !surface.is_override_redirect() {
|
||||
let loc = data
|
||||
.pinnacle
|
||||
.space
|
||||
.element_location(&self.window)
|
||||
.expect("failed to get x11 win loc");
|
||||
|
@ -366,7 +367,7 @@ pub fn move_surface_if_resized(state: &mut State, surface: &WlSurface) {
|
|||
return;
|
||||
};
|
||||
|
||||
let Some(mut window_loc) = state.space.element_location(&window) else {
|
||||
let Some(mut window_loc) = state.pinnacle.space.element_location(&window) else {
|
||||
return;
|
||||
};
|
||||
let geometry = window.geometry();
|
||||
|
@ -413,6 +414,7 @@ pub fn move_surface_if_resized(state: &mut State, surface: &WlSurface) {
|
|||
}
|
||||
|
||||
let size = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_geometry(&window)
|
||||
.expect("called element_geometry on unmapped window")
|
||||
|
@ -426,7 +428,10 @@ pub fn move_surface_if_resized(state: &mut State, surface: &WlSurface) {
|
|||
});
|
||||
|
||||
if new_loc.0.is_some() || new_loc.1.is_some() {
|
||||
state.space.map_element(window.clone(), window_loc, false);
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.map_element(window.clone(), window_loc, false);
|
||||
|
||||
if let Some(surface) = window.x11_surface() {
|
||||
if !surface.is_override_redirect() {
|
||||
|
@ -463,6 +468,7 @@ pub fn resize_request_client(
|
|||
}
|
||||
|
||||
let initial_window_loc = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_location(&window)
|
||||
.expect("resize request called on unmapped window");
|
||||
|
@ -513,6 +519,7 @@ pub fn resize_request_server(
|
|||
}
|
||||
|
||||
let initial_window_loc = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_location(&window)
|
||||
.expect("resize request called on unmapped window");
|
||||
|
|
112
src/handlers.rs
112
src/handlers.rs
|
@ -76,7 +76,7 @@ impl BufferHandler for State {
|
|||
|
||||
impl CompositorHandler for State {
|
||||
fn compositor_state(&mut self) -> &mut CompositorState {
|
||||
&mut self.compositor_state
|
||||
&mut self.pinnacle.compositor_state
|
||||
}
|
||||
|
||||
fn new_surface(&mut self, surface: &WlSurface) {
|
||||
|
@ -97,12 +97,16 @@ impl CompositorHandler for State {
|
|||
let client = surface
|
||||
.client()
|
||||
.expect("Surface has no client/is no longer alive");
|
||||
let res = state.loop_handle.insert_source(source, move |_, _, state| {
|
||||
let res =
|
||||
state
|
||||
.client_compositor_state(&client)
|
||||
.blocker_cleared(state, &state.display_handle.clone());
|
||||
Ok(())
|
||||
});
|
||||
.pinnacle
|
||||
.loop_handle
|
||||
.insert_source(source, move |_, _, state| {
|
||||
state
|
||||
.client_compositor_state(&client)
|
||||
.blocker_cleared(state, &state.pinnacle.display_handle.clone());
|
||||
Ok(())
|
||||
});
|
||||
if res.is_ok() {
|
||||
compositor::add_blocker(surface, blocker);
|
||||
}
|
||||
|
@ -129,14 +133,15 @@ impl CompositorHandler for State {
|
|||
if let Some(window) = self.window_for_surface(&root) {
|
||||
window.on_commit();
|
||||
if let Some(loc) = window.with_state_mut(|state| state.target_loc.take()) {
|
||||
self.space.map_element(window.clone(), loc, false);
|
||||
self.pinnacle.space.map_element(window.clone(), loc, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.popup_manager.commit(surface);
|
||||
self.pinnacle.popup_manager.commit(surface);
|
||||
|
||||
if let Some(new_window) = self
|
||||
.pinnacle
|
||||
.new_windows
|
||||
.iter()
|
||||
.find(|win| win.wl_surface().as_ref() == Some(surface))
|
||||
|
@ -149,8 +154,8 @@ impl CompositorHandler for State {
|
|||
};
|
||||
|
||||
if is_mapped {
|
||||
self.new_windows.retain(|win| win != &new_window);
|
||||
self.windows.push(new_window.clone());
|
||||
self.pinnacle.new_windows.retain(|win| win != &new_window);
|
||||
self.pinnacle.windows.push(new_window.clone());
|
||||
|
||||
if let Some(output) = self.focused_output() {
|
||||
tracing::debug!("Placing toplevel");
|
||||
|
@ -161,7 +166,8 @@ impl CompositorHandler for State {
|
|||
// FIXME: I'm mapping way offscreen here then sending a frame to prevent a window from
|
||||
// | mapping with its default geometry then immediately resizing
|
||||
// | because I don't set a target geometry before the initial configure.
|
||||
self.space
|
||||
self.pinnacle
|
||||
.space
|
||||
.map_element(new_window.clone(), (1000000, 0), true);
|
||||
|
||||
self.raise_window(new_window.clone(), true);
|
||||
|
@ -172,14 +178,15 @@ impl CompositorHandler for State {
|
|||
self.request_layout(&focused_output);
|
||||
new_window.send_frame(
|
||||
&focused_output,
|
||||
self.clock.now(),
|
||||
self.pinnacle.clock.now(),
|
||||
Some(Duration::ZERO),
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
}
|
||||
|
||||
self.loop_handle.insert_idle(move |state| {
|
||||
self.pinnacle.loop_handle.insert_idle(move |state| {
|
||||
state
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard") // FIXME: actually handle error
|
||||
|
@ -202,7 +209,7 @@ impl CompositorHandler for State {
|
|||
crate::grab::resize_grab::move_surface_if_resized(self, surface);
|
||||
|
||||
let outputs = if let Some(window) = self.window_for_surface(surface) {
|
||||
let mut outputs = self.space.outputs_for_element(&window);
|
||||
let mut outputs = self.pinnacle.space.outputs_for_element(&window);
|
||||
|
||||
// When the window hasn't been mapped `outputs` is empty,
|
||||
// so also trigger a render using the window's tags' output
|
||||
|
@ -211,24 +218,26 @@ impl CompositorHandler for State {
|
|||
}
|
||||
outputs // surface is a window
|
||||
} else if let Some(window) = self.window_for_surface(&root) {
|
||||
let mut outputs = self.space.outputs_for_element(&window);
|
||||
let mut outputs = self.pinnacle.space.outputs_for_element(&window);
|
||||
if let Some(output) = window.output(self) {
|
||||
outputs.push(output);
|
||||
}
|
||||
outputs // surface is a root window
|
||||
} else if let Some(PopupKind::Xdg(surf)) = self.popup_manager.find_popup(surface) {
|
||||
} else if let Some(PopupKind::Xdg(surf)) = self.pinnacle.popup_manager.find_popup(surface) {
|
||||
let geo = surf.with_pending_state(|state| state.geometry);
|
||||
let outputs = self
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.filter_map(|output| {
|
||||
let op_geo = self.space.output_geometry(output);
|
||||
let op_geo = self.pinnacle.space.output_geometry(output);
|
||||
op_geo.and_then(|op_geo| op_geo.overlaps_or_touches(geo).then_some(output))
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
outputs
|
||||
} else if let Some(output) = self
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.find(|op| {
|
||||
|
@ -285,7 +294,7 @@ fn ensure_initial_configure(surface: &WlSurface, state: &mut State) {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some(popup) = state.popup_manager.find_popup(surface) {
|
||||
if let Some(popup) = state.pinnacle.popup_manager.find_popup(surface) {
|
||||
let PopupKind::Xdg(popup) = &popup else { return };
|
||||
let initial_configure_sent = compositor::with_states(surface, |states| {
|
||||
states
|
||||
|
@ -304,7 +313,7 @@ fn ensure_initial_configure(surface: &WlSurface, state: &mut State) {
|
|||
return;
|
||||
}
|
||||
|
||||
if let Some(output) = state.space.outputs().find(|op| {
|
||||
if let Some(output) = state.pinnacle.space.outputs().find(|op| {
|
||||
let map = layer_map_for_output(op);
|
||||
map.layer_for_surface(surface, WindowSurfaceType::TOPLEVEL)
|
||||
.is_some()
|
||||
|
@ -338,11 +347,11 @@ impl ClientDndGrabHandler for State {
|
|||
icon: Option<WlSurface>,
|
||||
_seat: Seat<Self>,
|
||||
) {
|
||||
self.dnd_icon = icon;
|
||||
self.pinnacle.dnd_icon = icon;
|
||||
}
|
||||
|
||||
fn dropped(&mut self, _seat: Seat<Self>) {
|
||||
self.dnd_icon = None;
|
||||
self.pinnacle.dnd_icon = None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -357,7 +366,7 @@ impl SelectionHandler for State {
|
|||
source: Option<SelectionSource>,
|
||||
_seat: Seat<Self>,
|
||||
) {
|
||||
if let Some(xwm) = self.xwm.as_mut() {
|
||||
if let Some(xwm) = self.pinnacle.xwm.as_mut() {
|
||||
if let Err(err) = xwm.new_selection(ty, source.map(|source| source.mime_types())) {
|
||||
tracing::warn!(?err, ?ty, "Failed to set Xwayland selection");
|
||||
}
|
||||
|
@ -372,8 +381,10 @@ impl SelectionHandler for State {
|
|||
_seat: Seat<Self>,
|
||||
_user_data: &(),
|
||||
) {
|
||||
if let Some(xwm) = self.xwm.as_mut() {
|
||||
if let Err(err) = xwm.send_selection(ty, mime_type, fd, self.loop_handle.clone()) {
|
||||
if let Some(xwm) = self.pinnacle.xwm.as_mut() {
|
||||
if let Err(err) =
|
||||
xwm.send_selection(ty, mime_type, fd, self.pinnacle.loop_handle.clone())
|
||||
{
|
||||
tracing::warn!(?err, "Failed to send primary (X11 -> Wayland)");
|
||||
}
|
||||
}
|
||||
|
@ -382,21 +393,21 @@ impl SelectionHandler for State {
|
|||
|
||||
impl DataDeviceHandler for State {
|
||||
fn data_device_state(&self) -> &DataDeviceState {
|
||||
&self.data_device_state
|
||||
&self.pinnacle.data_device_state
|
||||
}
|
||||
}
|
||||
delegate_data_device!(State);
|
||||
|
||||
impl PrimarySelectionHandler for State {
|
||||
fn primary_selection_state(&self) -> &PrimarySelectionState {
|
||||
&self.primary_selection_state
|
||||
&self.pinnacle.primary_selection_state
|
||||
}
|
||||
}
|
||||
delegate_primary_selection!(State);
|
||||
|
||||
impl DataControlHandler for State {
|
||||
fn data_control_state(&self) -> &DataControlState {
|
||||
&self.data_control_state
|
||||
&self.pinnacle.data_control_state
|
||||
}
|
||||
}
|
||||
delegate_data_control!(State);
|
||||
|
@ -407,28 +418,29 @@ impl SeatHandler for State {
|
|||
type TouchFocus = PointerFocusTarget;
|
||||
|
||||
fn seat_state(&mut self) -> &mut SeatState<Self> {
|
||||
&mut self.seat_state
|
||||
&mut self.pinnacle.seat_state
|
||||
}
|
||||
|
||||
fn cursor_image(&mut self, _seat: &Seat<Self>, image: CursorImageStatus) {
|
||||
self.cursor_status = image;
|
||||
self.pinnacle.cursor_status = image;
|
||||
}
|
||||
|
||||
fn focus_changed(&mut self, seat: &Seat<Self>, focused: Option<&Self::KeyboardFocus>) {
|
||||
let focus_client = focused.and_then(|foc_target| {
|
||||
self.display_handle
|
||||
self.pinnacle
|
||||
.display_handle
|
||||
.get_client(foc_target.wl_surface()?.id())
|
||||
.ok()
|
||||
});
|
||||
set_data_device_focus(&self.display_handle, seat, focus_client.clone());
|
||||
set_primary_focus(&self.display_handle, seat, focus_client);
|
||||
set_data_device_focus(&self.pinnacle.display_handle, seat, focus_client.clone());
|
||||
set_primary_focus(&self.pinnacle.display_handle, seat, focus_client);
|
||||
}
|
||||
}
|
||||
delegate_seat!(State);
|
||||
|
||||
impl ShmHandler for State {
|
||||
fn shm_state(&self) -> &ShmState {
|
||||
&self.shm_state
|
||||
&self.pinnacle.shm_state
|
||||
}
|
||||
}
|
||||
delegate_shm!(State);
|
||||
|
@ -466,17 +478,25 @@ impl FractionalScaleHandler for State {
|
|||
desktop::utils::surface_primary_scanout_output(&root, states)
|
||||
.or_else(|| {
|
||||
self.window_for_surface(&root).and_then(|window| {
|
||||
self.space.outputs_for_element(&window).first().cloned()
|
||||
self.pinnacle
|
||||
.space
|
||||
.outputs_for_element(&window)
|
||||
.first()
|
||||
.cloned()
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
self.window_for_surface(&root).and_then(|window| {
|
||||
self.space.outputs_for_element(&window).first().cloned()
|
||||
self.pinnacle
|
||||
.space
|
||||
.outputs_for_element(&window)
|
||||
.first()
|
||||
.cloned()
|
||||
})
|
||||
}
|
||||
})
|
||||
.or_else(|| self.space.outputs().next().cloned());
|
||||
.or_else(|| self.pinnacle.space.outputs().next().cloned());
|
||||
if let Some(output) = primary_scanout_output {
|
||||
fractional_scale::with_fractional_scale(states, |fractional_scale| {
|
||||
fractional_scale.set_preferred_scale(output.current_scale().fractional_scale());
|
||||
|
@ -494,7 +514,7 @@ delegate_presentation!(State);
|
|||
|
||||
impl WlrLayerShellHandler for State {
|
||||
fn shell_state(&mut self) -> &mut WlrLayerShellState {
|
||||
&mut self.layer_shell_state
|
||||
&mut self.pinnacle.layer_shell_state
|
||||
}
|
||||
|
||||
fn new_layer_surface(
|
||||
|
@ -508,7 +528,7 @@ impl WlrLayerShellHandler for State {
|
|||
let output = output
|
||||
.as_ref()
|
||||
.and_then(Output::from_resource)
|
||||
.or_else(|| self.space.outputs().next().cloned());
|
||||
.or_else(|| self.pinnacle.space.outputs().next().cloned());
|
||||
|
||||
let Some(output) = output else {
|
||||
error!("New layer surface, but there was no output to map it on");
|
||||
|
@ -521,14 +541,14 @@ impl WlrLayerShellHandler for State {
|
|||
error!("Failed to map layer surface: {err}");
|
||||
}
|
||||
|
||||
self.loop_handle.insert_idle(move |state| {
|
||||
self.pinnacle.loop_handle.insert_idle(move |state| {
|
||||
state.request_layout(&output);
|
||||
});
|
||||
}
|
||||
|
||||
fn layer_destroyed(&mut self, surface: wlr_layer::LayerSurface) {
|
||||
let mut output: Option<Output> = None;
|
||||
if let Some((mut map, layer, op)) = self.space.outputs().find_map(|o| {
|
||||
if let Some((mut map, layer, op)) = self.pinnacle.space.outputs().find_map(|o| {
|
||||
let map = layer_map_for_output(o);
|
||||
let layer = map
|
||||
.layers()
|
||||
|
@ -541,7 +561,7 @@ impl WlrLayerShellHandler for State {
|
|||
}
|
||||
|
||||
if let Some(output) = output {
|
||||
self.loop_handle.insert_idle(move |state| {
|
||||
self.pinnacle.loop_handle.insert_idle(move |state| {
|
||||
state.request_layout(&output);
|
||||
});
|
||||
}
|
||||
|
@ -567,7 +587,7 @@ delegate_screencopy!(State);
|
|||
|
||||
impl GammaControlHandler for State {
|
||||
fn gamma_control_manager_state(&mut self) -> &mut GammaControlManagerState {
|
||||
&mut self.gamma_control_manager_state
|
||||
&mut self.pinnacle.gamma_control_manager_state
|
||||
}
|
||||
|
||||
fn get_gamma_size(&mut self, output: &Output) -> Option<u32> {
|
||||
|
@ -636,13 +656,13 @@ impl State {
|
|||
}
|
||||
|
||||
let (root_global_loc, output) = if let Some(win) = self.window_for_surface(&root) {
|
||||
let win_geo = self.space.element_geometry(&win)?;
|
||||
let win_geo = self.pinnacle.space.element_geometry(&win)?;
|
||||
(win_geo.loc, self.focused_output()?.clone())
|
||||
} else {
|
||||
self.space.outputs().find_map(|op| {
|
||||
self.pinnacle.space.outputs().find_map(|op| {
|
||||
let layer_map = layer_map_for_output(op);
|
||||
let layer = layer_map.layer_for_surface(&root, WindowSurfaceType::TOPLEVEL)?;
|
||||
let output_loc = self.space.output_geometry(op)?.loc;
|
||||
let output_loc = self.pinnacle.space.output_geometry(op)?.loc;
|
||||
Some((
|
||||
layer_map.layer_geometry(layer)?.loc + output_loc,
|
||||
op.clone(),
|
||||
|
@ -656,7 +676,7 @@ impl State {
|
|||
root_global_loc + get_popup_toplevel_coords(&PopupKind::Xdg(popup.clone()))
|
||||
};
|
||||
|
||||
let mut output_geo = self.space.output_geometry(&output)?;
|
||||
let mut output_geo = self.pinnacle.space.output_geometry(&output)?;
|
||||
|
||||
// Make local to parent
|
||||
output_geo.loc -= parent_global_loc;
|
||||
|
|
|
@ -31,7 +31,7 @@ use crate::{
|
|||
|
||||
impl XdgShellHandler for State {
|
||||
fn xdg_shell_state(&mut self) -> &mut XdgShellState {
|
||||
&mut self.xdg_shell_state
|
||||
&mut self.pinnacle.xdg_shell_state
|
||||
}
|
||||
|
||||
fn new_toplevel(&mut self, surface: ToplevelSurface) {
|
||||
|
@ -43,24 +43,24 @@ impl XdgShellHandler for State {
|
|||
});
|
||||
|
||||
let window = WindowElement::new(Window::new_wayland_window(surface.clone()));
|
||||
self.new_windows.push(window);
|
||||
self.pinnacle.new_windows.push(window);
|
||||
}
|
||||
|
||||
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
|
||||
tracing::debug!("toplevel destroyed");
|
||||
self.windows.retain(|window| {
|
||||
self.pinnacle.windows.retain(|window| {
|
||||
window
|
||||
.wl_surface()
|
||||
.is_some_and(|surf| &surf != surface.wl_surface())
|
||||
});
|
||||
|
||||
self.z_index_stack.retain(|window| {
|
||||
self.pinnacle.z_index_stack.retain(|window| {
|
||||
window
|
||||
.wl_surface()
|
||||
.is_some_and(|surf| &surf != surface.wl_surface())
|
||||
});
|
||||
|
||||
for output in self.space.outputs() {
|
||||
for output in self.pinnacle.space.outputs() {
|
||||
output.with_state_mut(|state| {
|
||||
state.focus_stack.stack.retain(|window| {
|
||||
window
|
||||
|
@ -87,7 +87,8 @@ impl XdgShellHandler for State {
|
|||
toplevel.send_configure();
|
||||
}
|
||||
}
|
||||
self.seat
|
||||
self.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard")
|
||||
.set_focus(self, focus, SERIAL_COUNTER.next_serial());
|
||||
|
@ -101,14 +102,18 @@ impl XdgShellHandler for State {
|
|||
|
||||
self.position_popup(&surface);
|
||||
|
||||
if let Err(err) = self.popup_manager.track_popup(PopupKind::from(surface)) {
|
||||
if let Err(err) = self
|
||||
.pinnacle
|
||||
.popup_manager
|
||||
.track_popup(PopupKind::from(surface))
|
||||
{
|
||||
tracing::warn!("failed to track popup: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
fn popup_destroyed(&mut self, _surface: PopupSurface) {
|
||||
// TODO: only schedule on the outputs the popup is on
|
||||
for output in self.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
for output in self.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
|
||||
self.schedule_render(&output);
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +169,7 @@ impl XdgShellHandler for State {
|
|||
self.window_for_surface(&root)
|
||||
.map(KeyboardFocusTarget::Window)
|
||||
.or_else(|| {
|
||||
self.space.outputs().find_map(|op| {
|
||||
self.pinnacle.space.outputs().find_map(|op| {
|
||||
layer_map_for_output(op)
|
||||
.layer_for_surface(&root, WindowSurfaceType::TOPLEVEL)
|
||||
.cloned()
|
||||
|
@ -173,6 +178,7 @@ impl XdgShellHandler for State {
|
|||
})
|
||||
}) {
|
||||
if let Ok(mut grab) = self
|
||||
.pinnacle
|
||||
.popup_manager
|
||||
.grab_popup(root, popup_kind, &seat, serial)
|
||||
{
|
||||
|
@ -217,17 +223,23 @@ impl XdgShellHandler for State {
|
|||
.as_ref()
|
||||
.and_then(Output::from_resource)
|
||||
.or_else(|| {
|
||||
self.window_for_surface(wl_surface)
|
||||
.and_then(|window| self.space.outputs_for_element(&window).first().cloned())
|
||||
self.window_for_surface(wl_surface).and_then(|window| {
|
||||
self.pinnacle
|
||||
.space
|
||||
.outputs_for_element(&window)
|
||||
.first()
|
||||
.cloned()
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(output) = output {
|
||||
let Some(geometry) = self.space.output_geometry(&output) else {
|
||||
let Some(geometry) = self.pinnacle.space.output_geometry(&output) else {
|
||||
surface.send_configure();
|
||||
return;
|
||||
};
|
||||
|
||||
let client = self
|
||||
.pinnacle
|
||||
.display_handle
|
||||
.get_client(wl_surface.id())
|
||||
.expect("wl_surface had no client");
|
||||
|
|
|
@ -32,7 +32,7 @@ use crate::{
|
|||
|
||||
impl XwmHandler for State {
|
||||
fn xwm_state(&mut self, _xwm: XwmId) -> &mut X11Wm {
|
||||
self.xwm.as_mut().expect("xwm not in state")
|
||||
self.pinnacle.xwm.as_mut().expect("xwm not in state")
|
||||
}
|
||||
|
||||
fn new_window(&mut self, _xwm: XwmId, _window: X11Surface) {}
|
||||
|
@ -48,15 +48,18 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
let window = WindowElement::new(Window::new_x11_window(surface));
|
||||
self.space.map_element(window.clone(), (0, 0), true);
|
||||
self.pinnacle
|
||||
.space
|
||||
.map_element(window.clone(), (0, 0), true);
|
||||
let bbox = self
|
||||
.pinnacle
|
||||
.space
|
||||
.element_bbox(&window)
|
||||
.expect("called element_bbox on an unmapped window");
|
||||
|
||||
let output_size = self
|
||||
.focused_output()
|
||||
.and_then(|op| self.space.output_geometry(op))
|
||||
.and_then(|op| self.pinnacle.space.output_geometry(op))
|
||||
.map(|geo| geo.size)
|
||||
.unwrap_or((2, 2).into());
|
||||
|
||||
|
@ -78,7 +81,7 @@ impl XwmHandler for State {
|
|||
unreachable!()
|
||||
};
|
||||
|
||||
self.space.map_element(window.clone(), loc, true);
|
||||
self.pinnacle.space.map_element(window.clone(), loc, true);
|
||||
surface.set_mapped(true).expect("failed to map x11 window");
|
||||
|
||||
let bbox = Rectangle::from_loc_and_size(loc, bbox.size);
|
||||
|
@ -100,7 +103,7 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
// TODO: will an unmap -> map duplicate the window
|
||||
self.windows.push(window.clone());
|
||||
self.pinnacle.windows.push(window.clone());
|
||||
self.raise_window(window.clone(), true);
|
||||
|
||||
self.apply_window_rules(&window);
|
||||
|
@ -110,8 +113,9 @@ impl XwmHandler for State {
|
|||
self.request_layout(&output);
|
||||
}
|
||||
|
||||
self.loop_handle.insert_idle(move |state| {
|
||||
self.pinnacle.loop_handle.insert_idle(move |state| {
|
||||
state
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard") // FIXME: actually handle error
|
||||
|
@ -132,7 +136,7 @@ impl XwmHandler for State {
|
|||
|
||||
let window = WindowElement::new(Window::new_x11_window(surface));
|
||||
|
||||
self.windows.push(window.clone());
|
||||
self.pinnacle.windows.push(window.clone());
|
||||
|
||||
if let Some(output) = self.focused_output() {
|
||||
window.place_on_output(output);
|
||||
|
@ -141,7 +145,7 @@ impl XwmHandler for State {
|
|||
output.with_state_mut(|state| state.focus_stack.set_focus(window.clone()));
|
||||
}
|
||||
|
||||
self.space.map_element(window.clone(), loc, true);
|
||||
self.pinnacle.space.map_element(window.clone(), loc, true);
|
||||
self.raise_window(window.clone(), true);
|
||||
}
|
||||
|
||||
|
@ -159,7 +163,7 @@ impl XwmHandler for State {
|
|||
|
||||
fn unmapped_window(&mut self, _xwm: XwmId, surface: X11Surface) {
|
||||
trace!("XwmHandler::unmapped_window");
|
||||
for output in self.space.outputs() {
|
||||
for output in self.pinnacle.space.outputs() {
|
||||
output.with_state_mut(|state| {
|
||||
state.focus_stack.stack.retain(|win| {
|
||||
win.wl_surface()
|
||||
|
@ -169,18 +173,21 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
let win = self
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.find(|elem| matches!(elem.x11_surface(), Some(surf) if surf == &surface))
|
||||
.cloned();
|
||||
|
||||
if let Some(win) = win {
|
||||
self.windows
|
||||
self.pinnacle
|
||||
.windows
|
||||
.retain(|elem| win.wl_surface() != elem.wl_surface());
|
||||
self.z_index_stack
|
||||
self.pinnacle
|
||||
.z_index_stack
|
||||
.retain(|elem| win.wl_surface() != elem.wl_surface());
|
||||
|
||||
self.space.unmap_elem(&win);
|
||||
self.pinnacle.space.unmap_elem(&win);
|
||||
|
||||
if let Some(output) = win.output(self) {
|
||||
self.request_layout(&output);
|
||||
|
@ -196,7 +203,8 @@ impl XwmHandler for State {
|
|||
}
|
||||
}
|
||||
|
||||
self.seat
|
||||
self.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard")
|
||||
.set_focus(self, focus, SERIAL_COUNTER.next_serial());
|
||||
|
@ -213,7 +221,7 @@ impl XwmHandler for State {
|
|||
|
||||
fn destroyed_window(&mut self, _xwm: XwmId, surface: X11Surface) {
|
||||
trace!("XwmHandler::destroyed_window");
|
||||
for output in self.space.outputs() {
|
||||
for output in self.pinnacle.space.outputs() {
|
||||
output.with_state_mut(|state| {
|
||||
state.focus_stack.stack.retain(|win| {
|
||||
win.wl_surface()
|
||||
|
@ -223,6 +231,7 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
let win = self
|
||||
.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.find(|elem| {
|
||||
|
@ -238,10 +247,12 @@ impl XwmHandler for State {
|
|||
|
||||
// INFO: comparing the windows doesn't work so wlsurface it is
|
||||
// self.windows.retain(|elem| &win != elem);
|
||||
self.windows
|
||||
self.pinnacle
|
||||
.windows
|
||||
.retain(|elem| win.wl_surface() != elem.wl_surface());
|
||||
|
||||
self.z_index_stack
|
||||
self.pinnacle
|
||||
.z_index_stack
|
||||
.retain(|elem| win.wl_surface() != elem.wl_surface());
|
||||
|
||||
if let Some(output) = win.output(self) {
|
||||
|
@ -258,7 +269,8 @@ impl XwmHandler for State {
|
|||
}
|
||||
}
|
||||
|
||||
self.seat
|
||||
self.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard")
|
||||
.set_focus(self, focus, SERIAL_COUNTER.next_serial());
|
||||
|
@ -281,6 +293,7 @@ impl XwmHandler for State {
|
|||
) {
|
||||
trace!("XwmHandler::configure_request");
|
||||
let floating_or_override_redirect = self
|
||||
.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.find(|win| win.x11_surface() == Some(&window))
|
||||
|
@ -320,6 +333,7 @@ impl XwmHandler for State {
|
|||
_above: Option<smithay::reexports::x11rb::protocol::xproto::Window>,
|
||||
) {
|
||||
let Some(win) = self
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.find(|elem| {
|
||||
|
@ -331,7 +345,7 @@ impl XwmHandler for State {
|
|||
return;
|
||||
};
|
||||
|
||||
self.space.map_element(win, geometry.loc, true);
|
||||
self.pinnacle.space.map_element(win, geometry.loc, true);
|
||||
}
|
||||
|
||||
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
|
||||
|
@ -416,7 +430,7 @@ impl XwmHandler for State {
|
|||
resize_edge: smithay::xwayland::xwm::ResizeEdge,
|
||||
) {
|
||||
let Some(wl_surf) = window.wl_surface() else { return };
|
||||
let seat = self.seat.clone();
|
||||
let seat = self.pinnacle.seat.clone();
|
||||
|
||||
// We use the server one and not the client because windows like Steam don't provide
|
||||
// GrabStartData, so we need to create it ourselves.
|
||||
|
@ -432,7 +446,7 @@ impl XwmHandler for State {
|
|||
|
||||
fn move_request(&mut self, _xwm: XwmId, window: X11Surface, button: u32) {
|
||||
let Some(wl_surf) = window.wl_surface() else { return };
|
||||
let seat = self.seat.clone();
|
||||
let seat = self.pinnacle.seat.clone();
|
||||
|
||||
// We use the server one and not the client because windows like Steam don't provide
|
||||
// GrabStartData, so we need to create it ourselves.
|
||||
|
@ -446,7 +460,8 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
fn allow_selection_access(&mut self, xwm: XwmId, _selection: SelectionTarget) -> bool {
|
||||
self.seat
|
||||
self.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.and_then(|kb| kb.current_focus())
|
||||
.is_some_and(|focus| {
|
||||
|
@ -468,7 +483,9 @@ impl XwmHandler for State {
|
|||
) {
|
||||
match selection {
|
||||
SelectionTarget::Clipboard => {
|
||||
if let Err(err) = request_data_device_client_selection(&self.seat, mime_type, fd) {
|
||||
if let Err(err) =
|
||||
request_data_device_client_selection(&self.pinnacle.seat, mime_type, fd)
|
||||
{
|
||||
error!(
|
||||
?err,
|
||||
"Failed to request current wayland clipboard for XWayland"
|
||||
|
@ -476,7 +493,9 @@ impl XwmHandler for State {
|
|||
}
|
||||
}
|
||||
SelectionTarget::Primary => {
|
||||
if let Err(err) = request_primary_client_selection(&self.seat, mime_type, fd) {
|
||||
if let Err(err) =
|
||||
request_primary_client_selection(&self.pinnacle.seat, mime_type, fd)
|
||||
{
|
||||
error!(
|
||||
?err,
|
||||
"Failed to request current wayland primary selection for XWayland"
|
||||
|
@ -489,10 +508,20 @@ impl XwmHandler for State {
|
|||
fn new_selection(&mut self, _xwm: XwmId, selection: SelectionTarget, mime_types: Vec<String>) {
|
||||
match selection {
|
||||
SelectionTarget::Clipboard => {
|
||||
set_data_device_selection(&self.display_handle, &self.seat, mime_types, ());
|
||||
set_data_device_selection(
|
||||
&self.pinnacle.display_handle,
|
||||
&self.pinnacle.seat,
|
||||
mime_types,
|
||||
(),
|
||||
);
|
||||
}
|
||||
SelectionTarget::Primary => {
|
||||
set_primary_selection(&self.display_handle, &self.seat, mime_types, ());
|
||||
set_primary_selection(
|
||||
&self.pinnacle.display_handle,
|
||||
&self.pinnacle.seat,
|
||||
mime_types,
|
||||
(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -500,13 +529,13 @@ impl XwmHandler for State {
|
|||
fn cleared_selection(&mut self, _xwm: XwmId, selection: SelectionTarget) {
|
||||
match selection {
|
||||
SelectionTarget::Clipboard => {
|
||||
if current_data_device_selection_userdata(&self.seat).is_some() {
|
||||
clear_data_device_selection(&self.display_handle, &self.seat);
|
||||
if current_data_device_selection_userdata(&self.pinnacle.seat).is_some() {
|
||||
clear_data_device_selection(&self.pinnacle.display_handle, &self.pinnacle.seat);
|
||||
}
|
||||
}
|
||||
SelectionTarget::Primary => {
|
||||
if current_primary_selection_userdata(&self.seat).is_some() {
|
||||
clear_primary_selection(&self.display_handle, &self.seat);
|
||||
if current_primary_selection_userdata(&self.pinnacle.seat).is_some() {
|
||||
clear_primary_selection(&self.pinnacle.display_handle, &self.pinnacle.seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -514,12 +543,13 @@ impl XwmHandler for State {
|
|||
}
|
||||
|
||||
impl State {
|
||||
pub fn fixup_xwayland_internal_z_indices(&mut self) {
|
||||
let Some(xwm) = self.xwm.as_mut() else {
|
||||
pub fn fixup_xwayland_window_layering(&mut self) {
|
||||
let Some(xwm) = self.pinnacle.xwm.as_mut() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let x11_wins = self
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.filter(|win| win.is_on_active_tag())
|
||||
|
|
121
src/input.rs
121
src/input.rs
|
@ -171,14 +171,16 @@ impl State {
|
|||
{
|
||||
let point: Point<f64, Logical> = point.into();
|
||||
|
||||
let output = self.space.outputs().find(|op| {
|
||||
self.space
|
||||
let output = self.pinnacle.space.outputs().find(|op| {
|
||||
self.pinnacle
|
||||
.space
|
||||
.output_geometry(op)
|
||||
.expect("called output_geometry on unmapped output (this shouldn't happen here)")
|
||||
.contains(point.to_i32_round())
|
||||
})?;
|
||||
|
||||
let output_geo = self
|
||||
.pinnacle
|
||||
.space
|
||||
.output_geometry(output)
|
||||
.expect("called output_geometry on unmapped output");
|
||||
|
@ -186,6 +188,7 @@ impl State {
|
|||
let mut fullscreen_and_up_split_at = 0;
|
||||
|
||||
for (i, win) in self
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.rev()
|
||||
|
@ -223,6 +226,7 @@ impl State {
|
|||
|windows: &[&WindowElement]| -> Option<(PointerFocusTarget, Point<i32, Logical>)> {
|
||||
windows.iter().find_map(|win| {
|
||||
let loc = self
|
||||
.pinnacle
|
||||
.space
|
||||
.element_location(win)
|
||||
.expect("called elem loc on unmapped win")
|
||||
|
@ -246,6 +250,7 @@ impl State {
|
|||
.or_else(|| {
|
||||
window_under(
|
||||
&self
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.rev()
|
||||
|
@ -258,6 +263,7 @@ impl State {
|
|||
.or_else(|| {
|
||||
window_under(
|
||||
&self
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.rev()
|
||||
|
@ -271,7 +277,7 @@ impl State {
|
|||
|
||||
/// Update the pointer focus if it's different from the previous one.
|
||||
pub fn update_pointer_focus(&mut self) {
|
||||
let Some(pointer) = self.seat.get_pointer() else {
|
||||
let Some(pointer) = self.pinnacle.seat.get_pointer() else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -291,7 +297,7 @@ impl State {
|
|||
&MotionEvent {
|
||||
location,
|
||||
serial: SERIAL_COUNTER.next_serial(),
|
||||
time: Duration::from(self.clock.now()).as_millis() as u32,
|
||||
time: Duration::from(self.pinnacle.clock.now()).as_millis() as u32,
|
||||
},
|
||||
);
|
||||
pointer.frame(self);
|
||||
|
@ -302,10 +308,14 @@ impl State {
|
|||
let time = event.time_msec();
|
||||
let press_state = event.state();
|
||||
|
||||
let reload_keybind = self.input_state.reload_keybind;
|
||||
let kill_keybind = self.input_state.kill_keybind;
|
||||
let reload_keybind = self.pinnacle.input_state.reload_keybind;
|
||||
let kill_keybind = self.pinnacle.input_state.kill_keybind;
|
||||
|
||||
let keyboard = self.seat.get_keyboard().expect("Seat has no keyboard");
|
||||
let keyboard = self
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat has no keyboard");
|
||||
|
||||
let modifiers = keyboard.modifier_state();
|
||||
|
||||
|
@ -318,11 +328,11 @@ impl State {
|
|||
}
|
||||
|
||||
// FIXME: Leds only update once another key is pressed.
|
||||
for device in self.input_state.libinput_devices.iter_mut() {
|
||||
for device in self.pinnacle.input_state.libinput_devices.iter_mut() {
|
||||
device.led_update(leds);
|
||||
}
|
||||
|
||||
for layer in self.layer_shell_state.layer_surfaces().rev() {
|
||||
for layer in self.pinnacle.layer_shell_state.layer_surfaces().rev() {
|
||||
let data = compositor::with_states(layer.wl_surface(), |states| {
|
||||
*states.cached_state.current::<LayerSurfaceCachedState>()
|
||||
});
|
||||
|
@ -332,18 +342,19 @@ impl State {
|
|||
wlr_layer::Layer::Top | wlr_layer::Layer::Overlay
|
||||
)
|
||||
{
|
||||
let layer_surface = self.space.outputs().find_map(|op| {
|
||||
let layer_surface = self.pinnacle.space.outputs().find_map(|op| {
|
||||
let map = layer_map_for_output(op);
|
||||
let cloned = map.layers().find(|l| l.layer_surface() == &layer).cloned();
|
||||
cloned
|
||||
});
|
||||
|
||||
if let Some(layer_surface) = layer_surface {
|
||||
match self.input_state.exclusive_layer_focus_stack.last() {
|
||||
match self.pinnacle.input_state.exclusive_layer_focus_stack.last() {
|
||||
Some(focus) => {
|
||||
let layer_focus = KeyboardFocusTarget::LayerSurface(layer_surface);
|
||||
if &layer_focus != focus {
|
||||
self.input_state
|
||||
self.pinnacle
|
||||
.input_state
|
||||
.exclusive_layer_focus_stack
|
||||
.push(layer_focus);
|
||||
}
|
||||
|
@ -351,10 +362,12 @@ impl State {
|
|||
// Push the previous focus on as this is the first exclusive layer surface
|
||||
// on screen. This lets us restore it when that layer surface goes away.
|
||||
None => {
|
||||
self.input_state
|
||||
self.pinnacle
|
||||
.input_state
|
||||
.exclusive_layer_focus_stack
|
||||
.extend(keyboard.current_focus());
|
||||
self.input_state
|
||||
self.pinnacle
|
||||
.input_state
|
||||
.exclusive_layer_focus_stack
|
||||
.push(KeyboardFocusTarget::LayerSurface(layer_surface));
|
||||
}
|
||||
|
@ -363,13 +376,19 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
while let Some(last) = self.input_state.exclusive_layer_focus_stack.pop() {
|
||||
while let Some(last) = self.pinnacle.input_state.exclusive_layer_focus_stack.pop() {
|
||||
if last.alive() {
|
||||
// If it's not empty then there's another exclusive layer surface
|
||||
// underneath. Otherwise `last` is the previous keyboard focus
|
||||
// and we don't need the stack anymore.
|
||||
if !self.input_state.exclusive_layer_focus_stack.is_empty() {
|
||||
self.input_state
|
||||
if !self
|
||||
.pinnacle
|
||||
.input_state
|
||||
.exclusive_layer_focus_stack
|
||||
.is_empty()
|
||||
{
|
||||
self.pinnacle
|
||||
.input_state
|
||||
.exclusive_layer_focus_stack
|
||||
.push(last.clone());
|
||||
}
|
||||
|
@ -392,9 +411,17 @@ impl State {
|
|||
let mod_sym = keysym.modified_sym();
|
||||
|
||||
if let (Some(sender), _) | (None, Some(sender)) = (
|
||||
state.input_state.keybinds.get(&(mod_mask, mod_sym)),
|
||||
state
|
||||
.pinnacle
|
||||
.input_state
|
||||
.keybinds
|
||||
.get(&(mod_mask, mod_sym)),
|
||||
raw_sym.and_then(|raw_sym| {
|
||||
state.input_state.keybinds.get(&(mod_mask, *raw_sym))
|
||||
state
|
||||
.pinnacle
|
||||
.input_state
|
||||
.keybinds
|
||||
.get(&(mod_mask, *raw_sym))
|
||||
}),
|
||||
) {
|
||||
return FilterResult::Intercept(KeyAction::CallCallback(sender.clone()));
|
||||
|
@ -429,7 +456,7 @@ impl State {
|
|||
}
|
||||
Some(KeyAction::ReloadConfig) => {
|
||||
info!("Reloading config");
|
||||
self.start_config(Some(self.config.dir(&self.xdg_base_dirs)))
|
||||
self.start_config(Some(self.pinnacle.config.dir(&self.pinnacle.xdg_base_dirs)))
|
||||
.expect("failed to restart config");
|
||||
}
|
||||
None => (),
|
||||
|
@ -437,8 +464,16 @@ impl State {
|
|||
}
|
||||
|
||||
fn pointer_button<I: InputBackend>(&mut self, event: I::PointerButtonEvent) {
|
||||
let pointer = self.seat.get_pointer().expect("Seat has no pointer"); // FIXME: handle err
|
||||
let keyboard = self.seat.get_keyboard().expect("Seat has no keyboard"); // FIXME: handle err
|
||||
let pointer = self
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_pointer()
|
||||
.expect("Seat has no pointer"); // FIXME: handle err
|
||||
let keyboard = self
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat has no keyboard"); // FIXME: handle err
|
||||
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
|
||||
|
@ -456,6 +491,7 @@ impl State {
|
|||
};
|
||||
|
||||
if let Some(stream) = self
|
||||
.pinnacle
|
||||
.input_state
|
||||
.mousebinds
|
||||
.get(&(mod_mask, button, mouse_edge))
|
||||
|
@ -489,7 +525,7 @@ impl State {
|
|||
keyboard.set_focus(self, focus.to_keyboard_focus_target(self), serial);
|
||||
}
|
||||
|
||||
for window in self.space.elements() {
|
||||
for window in self.pinnacle.space.elements() {
|
||||
if let Some(toplevel) = window.toplevel() {
|
||||
toplevel.send_configure();
|
||||
}
|
||||
|
@ -556,7 +592,11 @@ impl State {
|
|||
frame = frame.stop(Axis::Vertical);
|
||||
}
|
||||
|
||||
let pointer = self.seat.get_pointer().expect("Seat has no pointer");
|
||||
let pointer = self
|
||||
.pinnacle
|
||||
.seat
|
||||
.get_pointer()
|
||||
.expect("Seat has no pointer");
|
||||
|
||||
pointer.axis(self, frame);
|
||||
pointer.frame(self);
|
||||
|
@ -566,14 +606,15 @@ impl State {
|
|||
///
|
||||
/// This returns the nearest point inside an output.
|
||||
fn clamp_coords(&self, pos: Point<f64, Logical>) -> Point<f64, Logical> {
|
||||
if self.space.outputs().next().is_none() {
|
||||
if self.pinnacle.space.outputs().next().is_none() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
let (pos_x, pos_y) = pos.into();
|
||||
|
||||
let nearest_points = self.space.outputs().map(|op| {
|
||||
let nearest_points = self.pinnacle.space.outputs().map(|op| {
|
||||
let size = self
|
||||
.pinnacle
|
||||
.space
|
||||
.output_geometry(op)
|
||||
.expect("called output_geometry on unmapped output")
|
||||
|
@ -599,24 +640,30 @@ impl State {
|
|||
/// This *should* only be generated on the winit backend.
|
||||
/// Unless there's a case where it's generated on udev that I'm unaware of.
|
||||
fn pointer_motion_absolute<I: InputBackend>(&mut self, event: I::PointerMotionAbsoluteEvent) {
|
||||
let Some(pointer) = self.seat.get_pointer() else {
|
||||
let Some(pointer) = self.pinnacle.seat.get_pointer() else {
|
||||
tracing::error!("Pointer motion absolute received with no pointer on seat");
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(output) = self.space.outputs().next() else {
|
||||
let Some(output) = self.pinnacle.space.outputs().next() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(output_geo) = self.space.output_geometry(output) else {
|
||||
let Some(output_geo) = self.pinnacle.space.output_geometry(output) else {
|
||||
unreachable!("output should have a geometry as it was mapped");
|
||||
};
|
||||
|
||||
let pointer_loc = event.position_transformed(output_geo.size) + output_geo.loc.to_f64();
|
||||
let serial = SERIAL_COUNTER.next_serial();
|
||||
|
||||
if let Some(output) = self.space.output_under(pointer_loc).next().cloned() {
|
||||
self.output_focus_stack.set_focus(output);
|
||||
if let Some(output) = self
|
||||
.pinnacle
|
||||
.space
|
||||
.output_under(pointer_loc)
|
||||
.next()
|
||||
.cloned()
|
||||
{
|
||||
self.pinnacle.output_focus_stack.set_focus(output);
|
||||
}
|
||||
|
||||
let pointer_focus = self.pointer_focus_target_under(pointer_loc);
|
||||
|
@ -635,7 +682,7 @@ impl State {
|
|||
}
|
||||
|
||||
fn pointer_motion<I: InputBackend>(&mut self, event: I::PointerMotionEvent) {
|
||||
let Some(pointer) = self.seat.get_pointer() else {
|
||||
let Some(pointer) = self.pinnacle.seat.get_pointer() else {
|
||||
tracing::error!("Pointer motion received with no pointer on seat");
|
||||
return;
|
||||
};
|
||||
|
@ -647,8 +694,14 @@ impl State {
|
|||
// this event is never generated by winit
|
||||
pointer_loc = self.clamp_coords(pointer_loc);
|
||||
|
||||
if let Some(output) = self.space.output_under(pointer_loc).next().cloned() {
|
||||
self.output_focus_stack.set_focus(output);
|
||||
if let Some(output) = self
|
||||
.pinnacle
|
||||
.space
|
||||
.output_under(pointer_loc)
|
||||
.next()
|
||||
.cloned()
|
||||
{
|
||||
self.pinnacle.output_focus_stack.set_focus(output);
|
||||
}
|
||||
|
||||
let surface_under = self.pointer_focus_target_under(pointer_loc);
|
||||
|
|
|
@ -8,7 +8,8 @@ impl State {
|
|||
let mut device = match event {
|
||||
InputEvent::DeviceAdded { device } => device.clone(),
|
||||
InputEvent::DeviceRemoved { device } => {
|
||||
self.input_state
|
||||
self.pinnacle
|
||||
.input_state
|
||||
.libinput_devices
|
||||
.retain(|dev| dev != device);
|
||||
return;
|
||||
|
@ -16,14 +17,14 @@ impl State {
|
|||
_ => return,
|
||||
};
|
||||
|
||||
if self.input_state.libinput_devices.contains(&device) {
|
||||
if self.pinnacle.input_state.libinput_devices.contains(&device) {
|
||||
return;
|
||||
}
|
||||
|
||||
for setting in self.input_state.libinput_settings.values() {
|
||||
for setting in self.pinnacle.input_state.libinput_settings.values() {
|
||||
setting(&mut device);
|
||||
}
|
||||
|
||||
self.input_state.libinput_devices.push(device);
|
||||
self.pinnacle.input_state.libinput_devices.push(device);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@ impl State {
|
|||
) {
|
||||
let windows_on_foc_tags = output.with_state(|state| {
|
||||
let focused_tags = state.focused_tags().collect::<Vec<_>>();
|
||||
self.windows
|
||||
self.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.filter(|win| !win.is_x11_override_redirect())
|
||||
.filter(|win| {
|
||||
|
@ -52,7 +53,11 @@ impl State {
|
|||
})
|
||||
.cloned();
|
||||
|
||||
let output_geo = self.space.output_geometry(output).expect("no output geo");
|
||||
let output_geo = self
|
||||
.pinnacle
|
||||
.space
|
||||
.output_geometry(output)
|
||||
.expect("no output geo");
|
||||
|
||||
let non_exclusive_geo = {
|
||||
let map = layer_map_for_output(output);
|
||||
|
@ -125,7 +130,7 @@ impl State {
|
|||
WindowSurface::X11(_) => {
|
||||
let loc = win.with_state_mut(|state| state.target_loc.take());
|
||||
if let Some(loc) = loc {
|
||||
self.space.map_element(win.clone(), loc, false);
|
||||
self.pinnacle.space.map_element(win.clone(), loc, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,17 +138,20 @@ impl State {
|
|||
}
|
||||
|
||||
for (loc, window) in non_pending_wins {
|
||||
self.space.map_element(window, loc, false);
|
||||
self.pinnacle.space.map_element(window, loc, false);
|
||||
}
|
||||
|
||||
// HACK and FIXME:
|
||||
// FIXME:
|
||||
// We are sending frames here to get offscreen windows to commit and map.
|
||||
// Obviously this is a bad way to do this but its a bandaid solution
|
||||
// until decent transactional layout applications are implemented.
|
||||
for (win, _serial) in pending_wins {
|
||||
win.send_frame(output, self.clock.now(), Some(Duration::ZERO), |_, _| {
|
||||
Some(output.clone())
|
||||
});
|
||||
win.send_frame(
|
||||
output,
|
||||
self.pinnacle.clock.now(),
|
||||
Some(Duration::ZERO),
|
||||
|_, _| Some(output.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
self.fixup_z_layering();
|
||||
|
@ -151,15 +159,15 @@ impl State {
|
|||
|
||||
/// Swaps two windows in the main window vec and updates all windows.
|
||||
pub fn swap_window_positions(&mut self, win1: &WindowElement, win2: &WindowElement) {
|
||||
let win1_index = self.windows.iter().position(|win| win == win1);
|
||||
let win2_index = self.windows.iter().position(|win| win == win2);
|
||||
let win1_index = self.pinnacle.windows.iter().position(|win| win == win1);
|
||||
let win2_index = self.pinnacle.windows.iter().position(|win| win == win2);
|
||||
|
||||
if let (Some(first), Some(second)) = (win1_index, win2_index) {
|
||||
self.windows.swap(first, second);
|
||||
self.pinnacle.windows.swap(first, second);
|
||||
if let Some(output) = win1.output(self) {
|
||||
self.request_layout(&output);
|
||||
}
|
||||
self.layout_state.pending_swap = true;
|
||||
self.pinnacle.layout_state.pending_swap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,14 +187,15 @@ pub struct LayoutState {
|
|||
|
||||
impl State {
|
||||
pub fn request_layout(&mut self, output: &Output) {
|
||||
let Some(sender) = self.layout_state.layout_request_sender.as_ref() else {
|
||||
let Some(sender) = self.pinnacle.layout_state.layout_request_sender.as_ref() else {
|
||||
warn!("Layout requested but no client has connected to the layout service");
|
||||
return;
|
||||
};
|
||||
|
||||
let windows_on_foc_tags = output.with_state(|state| {
|
||||
let focused_tags = state.focused_tags().collect::<Vec<_>>();
|
||||
self.windows
|
||||
self.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.filter(|win| !win.is_x11_override_redirect())
|
||||
.filter(|win| {
|
||||
|
@ -221,12 +230,14 @@ impl State {
|
|||
output.with_state(|state| state.focused_tags().map(|tag| tag.id().0).collect());
|
||||
|
||||
let id = self
|
||||
.pinnacle
|
||||
.layout_state
|
||||
.id_maps
|
||||
.entry(output.clone())
|
||||
.or_insert(LayoutRequestId(0));
|
||||
|
||||
self.layout_state
|
||||
self.pinnacle
|
||||
.layout_state
|
||||
.pending_requests
|
||||
.entry(output.clone())
|
||||
.or_default()
|
||||
|
@ -261,6 +272,7 @@ impl State {
|
|||
};
|
||||
|
||||
let old_requests = self
|
||||
.pinnacle
|
||||
.layout_state
|
||||
.old_requests
|
||||
.entry(output.clone())
|
||||
|
@ -271,6 +283,7 @@ impl State {
|
|||
}
|
||||
|
||||
let pending = self
|
||||
.pinnacle
|
||||
.layout_state
|
||||
.pending_requests
|
||||
.entry(output.clone())
|
||||
|
@ -312,7 +325,7 @@ impl State {
|
|||
|
||||
self.schedule_render(&output);
|
||||
|
||||
self.layout_state.pending_swap = false;
|
||||
self.pinnacle.layout_state.pending_swap = false;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -132,18 +132,19 @@ async fn main() -> anyhow::Result<()> {
|
|||
event_loop.run(None, &mut state, |state| {
|
||||
state.update_pointer_focus();
|
||||
state.fixup_z_layering();
|
||||
state.space.refresh();
|
||||
state.popup_manager.cleanup();
|
||||
state.pinnacle.space.refresh();
|
||||
state.pinnacle.popup_manager.cleanup();
|
||||
|
||||
state
|
||||
.pinnacle
|
||||
.display_handle
|
||||
.flush_clients()
|
||||
.expect("failed to flush client buffers");
|
||||
|
||||
// TODO: couple these or something, this is really error-prone
|
||||
assert_eq!(
|
||||
state.windows.len(),
|
||||
state.z_index_stack.len(),
|
||||
state.pinnacle.windows.len(),
|
||||
state.pinnacle.z_index_stack.len(),
|
||||
"Length of `windows` and `z_index_stack` are different. \
|
||||
If you see this, report it to the developer."
|
||||
);
|
||||
|
@ -157,6 +158,8 @@ async fn main() -> anyhow::Result<()> {
|
|||
fn set_log_panic_hook() {
|
||||
let hook = std::panic::take_hook();
|
||||
std::panic::set_hook(Box::new(move |info| {
|
||||
let _span = tracing::error_span!("panic");
|
||||
let _span = _span.enter();
|
||||
error!("Panic occurred! Attempting to log backtrace");
|
||||
let buffer = gag::BufferRedirect::stderr();
|
||||
if let Ok(buffer) = buffer {
|
||||
|
|
|
@ -28,6 +28,7 @@ impl OutputName {
|
|||
/// Get the output with this name.
|
||||
pub fn output(&self, state: &State) -> Option<Output> {
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.find(|output| output.name() == self.0)
|
||||
|
@ -90,8 +91,8 @@ impl State {
|
|||
output.change_current_state(mode, transform, scale, location);
|
||||
if let Some(location) = location {
|
||||
info!(?location);
|
||||
self.space.map_output(output, location);
|
||||
self.signal_state.output_move.signal(|buf| {
|
||||
self.pinnacle.space.map_output(output, location);
|
||||
self.pinnacle.signal_state.output_move.signal(|buf| {
|
||||
buf.push_back(OutputMoveResponse {
|
||||
output_name: Some(output.name()),
|
||||
x: Some(location.x),
|
||||
|
@ -101,8 +102,8 @@ impl State {
|
|||
}
|
||||
if mode.is_some() || transform.is_some() || scale.is_some() {
|
||||
layer_map_for_output(output).arrange();
|
||||
self.signal_state.output_resize.signal(|buf| {
|
||||
let geo = self.space.output_geometry(output);
|
||||
self.pinnacle.signal_state.output_resize.signal(|buf| {
|
||||
let geo = self.pinnacle.space.output_geometry(output);
|
||||
buf.push_back(OutputResizeResponse {
|
||||
output_name: Some(output.name()),
|
||||
logical_width: geo.map(|geo| geo.size.w as u32),
|
||||
|
|
|
@ -349,7 +349,7 @@ impl State {
|
|||
/// Schedule a new render. This does nothing on the winit backend.
|
||||
pub fn schedule_render(&mut self, output: &Output) {
|
||||
if let Backend::Udev(udev) = &mut self.backend {
|
||||
udev.schedule_render(&self.loop_handle, output);
|
||||
udev.schedule_render(&self.pinnacle.loop_handle, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
140
src/state.rs
140
src/state.rs
|
@ -53,11 +53,14 @@ use crate::input::InputState;
|
|||
pub struct State {
|
||||
/// Which backend is currently running
|
||||
pub backend: Backend,
|
||||
pub pinnacle: Pinnacle,
|
||||
}
|
||||
|
||||
pub struct Pinnacle {
|
||||
/// A loop signal used to stop the compositor
|
||||
pub loop_signal: LoopSignal,
|
||||
/// A handle to the event loop
|
||||
pub loop_handle: LoopHandle<'static, Self>,
|
||||
pub loop_handle: LoopHandle<'static, State>,
|
||||
pub display_handle: DisplayHandle,
|
||||
pub clock: Clock<Monotonic>,
|
||||
|
||||
|
@ -67,7 +70,7 @@ pub struct State {
|
|||
|
||||
pub compositor_state: CompositorState,
|
||||
pub data_device_state: DataDeviceState,
|
||||
pub seat_state: SeatState<Self>,
|
||||
pub seat_state: SeatState<State>,
|
||||
pub shm_state: ShmState,
|
||||
pub output_manager_state: OutputManagerState,
|
||||
pub xdg_shell_state: XdgShellState,
|
||||
|
@ -150,8 +153,10 @@ impl State {
|
|||
info!("Fd raise success!");
|
||||
}
|
||||
|
||||
loop_handle.insert_source(socket, |stream, _metadata, data| {
|
||||
data.display_handle
|
||||
loop_handle.insert_source(socket, |stream, _metadata, state| {
|
||||
state
|
||||
.pinnacle
|
||||
.display_handle
|
||||
.insert_client(stream, Arc::new(ClientState::default()))
|
||||
.expect("Could not insert client into loop handle");
|
||||
})?;
|
||||
|
@ -191,7 +196,7 @@ impl State {
|
|||
display,
|
||||
} => {
|
||||
let mut wm = X11Wm::start_wm(
|
||||
state.loop_handle.clone(),
|
||||
state.pinnacle.loop_handle.clone(),
|
||||
dh_clone.clone(),
|
||||
connection,
|
||||
client,
|
||||
|
@ -209,19 +214,19 @@ impl State {
|
|||
|
||||
tracing::debug!("setting xwm and xdisplay");
|
||||
|
||||
state.xwm = Some(wm);
|
||||
state.xdisplay = Some(display);
|
||||
state.pinnacle.xwm = Some(wm);
|
||||
state.pinnacle.xdisplay = Some(display);
|
||||
|
||||
std::env::set_var("DISPLAY", format!(":{display}"));
|
||||
|
||||
if let Err(err) =
|
||||
state.start_config(Some(state.config.dir(&state.xdg_base_dirs)))
|
||||
{
|
||||
if let Err(err) = state.start_config(Some(
|
||||
state.pinnacle.config.dir(&state.pinnacle.xdg_base_dirs),
|
||||
)) {
|
||||
panic!("failed to start config: {err}");
|
||||
}
|
||||
}
|
||||
XWaylandEvent::Exited => {
|
||||
state.xwm.take();
|
||||
state.pinnacle.xwm.take();
|
||||
}
|
||||
});
|
||||
if let Err(err) = res {
|
||||
|
@ -241,69 +246,74 @@ impl State {
|
|||
|
||||
let state = Self {
|
||||
backend,
|
||||
loop_signal,
|
||||
loop_handle,
|
||||
display_handle: display_handle.clone(),
|
||||
clock: Clock::<Monotonic>::new(),
|
||||
compositor_state: CompositorState::new::<Self>(&display_handle),
|
||||
data_device_state: DataDeviceState::new::<Self>(&display_handle),
|
||||
seat_state,
|
||||
shm_state: ShmState::new::<Self>(&display_handle, vec![]),
|
||||
space: Space::<WindowElement>::default(),
|
||||
cursor_status: CursorImageStatus::default_named(),
|
||||
output_manager_state: OutputManagerState::new_with_xdg_output::<Self>(&display_handle),
|
||||
xdg_shell_state: XdgShellState::new::<Self>(&display_handle),
|
||||
viewporter_state: ViewporterState::new::<Self>(&display_handle),
|
||||
fractional_scale_manager_state: FractionalScaleManagerState::new::<Self>(
|
||||
&display_handle,
|
||||
),
|
||||
primary_selection_state,
|
||||
layer_shell_state: WlrLayerShellState::new::<Self>(&display_handle),
|
||||
data_control_state,
|
||||
screencopy_manager_state: ScreencopyManagerState::new::<Self, _>(
|
||||
&display_handle,
|
||||
|_| true,
|
||||
),
|
||||
gamma_control_manager_state: GammaControlManagerState::new::<Self, _>(
|
||||
&display_handle,
|
||||
|_| true,
|
||||
),
|
||||
relative_pointer_manager_state: RelativePointerManagerState::new::<Self>(
|
||||
&display_handle,
|
||||
),
|
||||
|
||||
input_state: InputState::new(),
|
||||
pinnacle: Pinnacle {
|
||||
loop_signal,
|
||||
loop_handle,
|
||||
display_handle: display_handle.clone(),
|
||||
clock: Clock::<Monotonic>::new(),
|
||||
compositor_state: CompositorState::new::<Self>(&display_handle),
|
||||
data_device_state: DataDeviceState::new::<Self>(&display_handle),
|
||||
seat_state,
|
||||
shm_state: ShmState::new::<Self>(&display_handle, vec![]),
|
||||
space: Space::<WindowElement>::default(),
|
||||
cursor_status: CursorImageStatus::default_named(),
|
||||
output_manager_state: OutputManagerState::new_with_xdg_output::<Self>(
|
||||
&display_handle,
|
||||
),
|
||||
xdg_shell_state: XdgShellState::new::<Self>(&display_handle),
|
||||
viewporter_state: ViewporterState::new::<Self>(&display_handle),
|
||||
fractional_scale_manager_state: FractionalScaleManagerState::new::<Self>(
|
||||
&display_handle,
|
||||
),
|
||||
primary_selection_state,
|
||||
layer_shell_state: WlrLayerShellState::new::<Self>(&display_handle),
|
||||
data_control_state,
|
||||
screencopy_manager_state: ScreencopyManagerState::new::<Self, _>(
|
||||
&display_handle,
|
||||
|_| true,
|
||||
),
|
||||
gamma_control_manager_state: GammaControlManagerState::new::<Self, _>(
|
||||
&display_handle,
|
||||
|_| true,
|
||||
),
|
||||
relative_pointer_manager_state: RelativePointerManagerState::new::<Self>(
|
||||
&display_handle,
|
||||
),
|
||||
|
||||
output_focus_stack: OutputFocusStack::default(),
|
||||
z_index_stack: Vec::new(),
|
||||
input_state: InputState::new(),
|
||||
|
||||
config: Config::new(no_config, config_dir),
|
||||
output_focus_stack: OutputFocusStack::default(),
|
||||
z_index_stack: Vec::new(),
|
||||
|
||||
seat,
|
||||
config: Config::new(no_config, config_dir),
|
||||
|
||||
dnd_icon: None,
|
||||
seat,
|
||||
|
||||
popup_manager: PopupManager::default(),
|
||||
dnd_icon: None,
|
||||
|
||||
windows: Vec::new(),
|
||||
new_windows: Vec::new(),
|
||||
popup_manager: PopupManager::default(),
|
||||
|
||||
xwayland,
|
||||
xwm: None,
|
||||
xdisplay: None,
|
||||
windows: Vec::new(),
|
||||
new_windows: Vec::new(),
|
||||
|
||||
system_processes: sysinfo::System::new_with_specifics(
|
||||
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
||||
),
|
||||
xwayland,
|
||||
xwm: None,
|
||||
xdisplay: None,
|
||||
|
||||
grpc_server_join_handle: None,
|
||||
system_processes: sysinfo::System::new_with_specifics(
|
||||
RefreshKind::new().with_processes(ProcessRefreshKind::new()),
|
||||
),
|
||||
|
||||
xdg_base_dirs: BaseDirectories::with_prefix("pinnacle")
|
||||
.context("couldn't create xdg BaseDirectories")?,
|
||||
grpc_server_join_handle: None,
|
||||
|
||||
signal_state: SignalState::default(),
|
||||
xdg_base_dirs: BaseDirectories::with_prefix("pinnacle")
|
||||
.context("couldn't create xdg BaseDirectories")?,
|
||||
|
||||
layout_state: LayoutState::default(),
|
||||
signal_state: SignalState::default(),
|
||||
|
||||
layout_state: LayoutState::default(),
|
||||
},
|
||||
};
|
||||
|
||||
Ok(state)
|
||||
|
@ -317,7 +327,7 @@ impl State {
|
|||
F1: Fn(&mut Self) -> bool + 'static,
|
||||
F2: FnOnce(&mut Self) + 'static,
|
||||
{
|
||||
self.loop_handle.insert_idle(|state| {
|
||||
self.pinnacle.loop_handle.insert_idle(|state| {
|
||||
if !condition(state) {
|
||||
state.schedule(condition, run);
|
||||
} else {
|
||||
|
@ -328,11 +338,11 @@ impl State {
|
|||
|
||||
pub fn shutdown(&mut self) {
|
||||
info!("Shutting down Pinnacle");
|
||||
self.loop_signal.stop();
|
||||
if let Some(join_handle) = self.config.config_join_handle.take() {
|
||||
self.pinnacle.loop_signal.stop();
|
||||
if let Some(join_handle) = self.pinnacle.config.config_join_handle.take() {
|
||||
join_handle.abort();
|
||||
}
|
||||
if let Some(shutdown_sender) = self.config.shutdown_sender.take() {
|
||||
if let Some(shutdown_sender) = self.pinnacle.config.shutdown_sender.take() {
|
||||
if let Err(err) = shutdown_sender.send(Ok(ShutdownWatchResponse {})) {
|
||||
warn!("Failed to send shutdown signal to config: {err}");
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ impl TagId {
|
|||
/// Get the tag associated with this id.
|
||||
pub fn tag(&self, state: &State) -> Option<Tag> {
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.flat_map(|op| op.with_state(|state| state.tags.clone()))
|
||||
|
@ -83,7 +84,7 @@ impl Tag {
|
|||
pub fn set_active(&self, active: bool, state: &mut State) {
|
||||
self.0.borrow_mut().active = active;
|
||||
|
||||
state.signal_state.tag_active.signal(|buf| {
|
||||
state.pinnacle.signal_state.tag_active.signal(|buf| {
|
||||
buf.push_back(
|
||||
pinnacle_api_defs::pinnacle::signal::v0alpha1::TagActiveResponse {
|
||||
tag_id: Some(self.id().0),
|
||||
|
@ -108,6 +109,7 @@ impl Tag {
|
|||
/// RefCell Safety: This uses RefCells on every mapped output.
|
||||
pub fn output(&self, state: &State) -> Option<Output> {
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.find(|output| output.with_state(|state| state.tags.iter().any(|tg| tg == self)))
|
||||
|
|
|
@ -212,11 +212,13 @@ impl WithState for WindowElement {
|
|||
impl State {
|
||||
/// Returns the [Window] associated with a given [WlSurface].
|
||||
pub fn window_for_surface(&self, surface: &WlSurface) -> Option<WindowElement> {
|
||||
self.space
|
||||
self.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.find(|window| window.wl_surface().map(|s| s == *surface).unwrap_or(false))
|
||||
.or_else(|| {
|
||||
self.windows
|
||||
self.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.find(|&win| win.wl_surface().is_some_and(|surf| &surf == surface))
|
||||
})
|
||||
|
@ -227,7 +229,8 @@ impl State {
|
|||
///
|
||||
/// Currently only used in `ensure_initial_configure` in [`handlers`][crate::handlers].
|
||||
pub fn new_window_for_surface(&self, surface: &WlSurface) -> Option<WindowElement> {
|
||||
self.new_windows
|
||||
self.pinnacle
|
||||
.new_windows
|
||||
.iter()
|
||||
.find(|&win| win.wl_surface().is_some_and(|surf| &surf == surface))
|
||||
.cloned()
|
||||
|
|
|
@ -170,7 +170,7 @@ pub enum FloatingOrTiled {
|
|||
impl State {
|
||||
pub fn apply_window_rules(&mut self, window: &WindowElement) {
|
||||
tracing::debug!("Applying window rules");
|
||||
for (cond, rule) in self.config.window_rules.iter() {
|
||||
for (cond, rule) in self.pinnacle.config.window_rules.iter() {
|
||||
if cond.is_met(self, window) {
|
||||
let WindowRule {
|
||||
output,
|
||||
|
@ -253,7 +253,7 @@ impl State {
|
|||
state.floating_or_tiled =
|
||||
window_state::FloatingOrTiled::Floating(rect)
|
||||
});
|
||||
self.space.map_element(window.clone(), *loc, false);
|
||||
self.pinnacle.space.map_element(window.clone(), *loc, false);
|
||||
}
|
||||
window_state::FloatingOrTiled::Tiled(rect) => {
|
||||
// If the window is tiled, don't set the size. Instead, set
|
||||
|
|
|
@ -30,6 +30,7 @@ impl WindowId {
|
|||
/// Get the window that has this WindowId.
|
||||
pub fn window(&self, state: &State) -> Option<WindowElement> {
|
||||
state
|
||||
.pinnacle
|
||||
.windows
|
||||
.iter()
|
||||
.find(|win| win.with_state(|state| &state.id == self))
|
||||
|
|
|
@ -55,18 +55,19 @@ where
|
|||
|
||||
event_loop.run(None, &mut state, |state| {
|
||||
state.fixup_z_layering();
|
||||
state.space.refresh();
|
||||
state.popup_manager.cleanup();
|
||||
state.pinnacle.space.refresh();
|
||||
state.pinnacle.popup_manager.cleanup();
|
||||
|
||||
state
|
||||
.pinnacle
|
||||
.display_handle
|
||||
.flush_clients()
|
||||
.expect("failed to flush client buffers");
|
||||
|
||||
// TODO: couple these or something, this is really error-prone
|
||||
assert_eq!(
|
||||
state.windows.len(),
|
||||
state.z_index_stack.len(),
|
||||
state.pinnacle.windows.len(),
|
||||
state.pinnacle.z_index_stack.len(),
|
||||
"Length of `windows` and `z_index_stack` are different. \
|
||||
If you see this, report it to the developer."
|
||||
);
|
||||
|
@ -77,6 +78,7 @@ where
|
|||
|
||||
pub fn output_for_name(state: &State, name: &str) -> Output {
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.outputs()
|
||||
.find(|op| op.name() == name)
|
||||
|
|
|
@ -124,8 +124,8 @@ mod process {
|
|||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.windows.len(), 1);
|
||||
assert_eq!(state.windows[0].class(), Some("foot".to_string()));
|
||||
assert_eq!(state.pinnacle.windows.len(), 1);
|
||||
assert_eq!(state.pinnacle.windows[0].class(), Some("foot".to_string()));
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -217,9 +217,9 @@ mod window {
|
|||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.config.window_rules.len(), 1);
|
||||
assert_eq!(state.pinnacle.config.window_rules.len(), 1);
|
||||
assert_eq!(
|
||||
state.config.window_rules[0],
|
||||
state.pinnacle.config.window_rules[0],
|
||||
(
|
||||
WindowRuleCondition {
|
||||
class: Some(vec!["firefox".to_string()]),
|
||||
|
@ -254,9 +254,9 @@ mod window {
|
|||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.config.window_rules.len(), 2);
|
||||
assert_eq!(state.pinnacle.config.window_rules.len(), 2);
|
||||
assert_eq!(
|
||||
state.config.window_rules[1],
|
||||
state.pinnacle.config.window_rules[1],
|
||||
(
|
||||
WindowRuleCondition {
|
||||
cond_all: Some(vec![WindowRuleCondition {
|
||||
|
@ -297,7 +297,7 @@ mod window {
|
|||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.windows.len(), 1);
|
||||
assert_eq!(state.pinnacle.windows.len(), 1);
|
||||
});
|
||||
|
||||
run_lua! { |Pinnacle|
|
||||
|
@ -307,7 +307,7 @@ mod window {
|
|||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.windows.len(), 0);
|
||||
assert_eq!(state.pinnacle.windows.len(), 0);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -329,7 +329,7 @@ mod window {
|
|||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(
|
||||
state.windows[0].with_state(|st| st
|
||||
state.pinnacle.windows[0].with_state(|st| st
|
||||
.tags
|
||||
.iter()
|
||||
.map(|tag| tag.name())
|
||||
|
@ -347,7 +347,7 @@ mod window {
|
|||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(
|
||||
state.windows[0].with_state(|st| st
|
||||
state.pinnacle.windows[0].with_state(|st| st
|
||||
.tags
|
||||
.iter()
|
||||
.map(|tag| tag.name())
|
||||
|
@ -365,7 +365,7 @@ mod window {
|
|||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(
|
||||
state.windows[0].with_state(|st| st
|
||||
state.pinnacle.windows[0].with_state(|st| st
|
||||
.tags
|
||||
.iter()
|
||||
.map(|tag| tag.name())
|
||||
|
@ -652,8 +652,8 @@ mod output {
|
|||
let original_op = output_for_name(state, DUMMY_OUTPUT_NAME);
|
||||
let first_op = output_for_name(state, "First");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
@ -674,9 +674,9 @@ mod output {
|
|||
let first_op = output_for_name(state, "First");
|
||||
let second_op = output_for_name(state, "Second");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.space.output_geometry(&second_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.pinnacle.space.output_geometry(&second_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
@ -727,10 +727,10 @@ mod output {
|
|||
let second_op = output_for_name(state, "Second");
|
||||
let third_op = output_for_name(state, "Third");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.space.output_geometry(&second_op).unwrap();
|
||||
let third_geo = state.space.output_geometry(&third_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.pinnacle.space.output_geometry(&second_op).unwrap();
|
||||
let third_geo = state.pinnacle.space.output_geometry(&third_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
@ -759,9 +759,9 @@ mod output {
|
|||
let first_op = output_for_name(state, "First");
|
||||
let third_op = output_for_name(state, "Third");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let third_geo = state.space.output_geometry(&third_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
let third_geo = state.pinnacle.space.output_geometry(&third_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
@ -793,7 +793,7 @@ async fn window_count_with_tag_is_correct() -> anyhow::Result<()> {
|
|||
|
||||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| assert_eq!(state.windows.len(), 1));
|
||||
with_state(&sender, |state| assert_eq!(state.pinnacle.windows.len(), 1));
|
||||
|
||||
run_lua! { |Pinnacle|
|
||||
for i = 1, 20 do
|
||||
|
@ -803,7 +803,9 @@ async fn window_count_with_tag_is_correct() -> anyhow::Result<()> {
|
|||
|
||||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| assert_eq!(state.windows.len(), 21));
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.pinnacle.windows.len(), 21)
|
||||
});
|
||||
|
||||
Ok(())
|
||||
})
|
||||
|
@ -819,7 +821,7 @@ async fn window_count_without_tag_is_correct() -> anyhow::Result<()> {
|
|||
|
||||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| assert_eq!(state.windows.len(), 1));
|
||||
with_state(&sender, |state| assert_eq!(state.pinnacle.windows.len(), 1));
|
||||
|
||||
Ok(())
|
||||
})
|
||||
|
@ -881,8 +883,8 @@ async fn spawned_window_has_correct_tags() -> anyhow::Result<()> {
|
|||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.windows.len(), 1);
|
||||
assert_eq!(state.windows[0].with_state(|st| st.tags.len()), 1);
|
||||
assert_eq!(state.pinnacle.windows.len(), 1);
|
||||
assert_eq!(state.pinnacle.windows[0].with_state(|st| st.tags.len()), 1);
|
||||
});
|
||||
|
||||
run_lua! { |Pinnacle|
|
||||
|
@ -894,10 +896,10 @@ async fn spawned_window_has_correct_tags() -> anyhow::Result<()> {
|
|||
sleep_secs(1);
|
||||
|
||||
with_state(&sender, |state| {
|
||||
assert_eq!(state.windows.len(), 2);
|
||||
assert_eq!(state.windows[1].with_state(|st| st.tags.len()), 2);
|
||||
assert_eq!(state.pinnacle.windows.len(), 2);
|
||||
assert_eq!(state.pinnacle.windows[1].with_state(|st| st.tags.len()), 2);
|
||||
assert_eq!(
|
||||
state.windows[1].with_state(|st| st
|
||||
state.pinnacle.windows[1].with_state(|st| st
|
||||
.tags
|
||||
.iter()
|
||||
.map(|tag| tag.name())
|
||||
|
|
|
@ -160,8 +160,8 @@ mod output {
|
|||
let original_op = output_for_name(state, DUMMY_OUTPUT_NAME);
|
||||
let first_op = output_for_name(state, "First");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
@ -182,9 +182,9 @@ mod output {
|
|||
let first_op = output_for_name(state, "First");
|
||||
let second_op = output_for_name(state, "Second");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.space.output_geometry(&second_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.pinnacle.space.output_geometry(&second_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
@ -262,10 +262,10 @@ mod output {
|
|||
let second_op = output_for_name(state, "Second");
|
||||
let third_op = output_for_name(state, "Third");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.space.output_geometry(&second_op).unwrap();
|
||||
let third_geo = state.space.output_geometry(&third_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
let second_geo = state.pinnacle.space.output_geometry(&second_op).unwrap();
|
||||
let third_geo = state.pinnacle.space.output_geometry(&third_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
@ -294,9 +294,9 @@ mod output {
|
|||
let first_op = output_for_name(state, "First");
|
||||
let third_op = output_for_name(state, "Third");
|
||||
|
||||
let original_geo = state.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.space.output_geometry(&first_op).unwrap();
|
||||
let third_geo = state.space.output_geometry(&third_op).unwrap();
|
||||
let original_geo = state.pinnacle.space.output_geometry(&original_op).unwrap();
|
||||
let first_geo = state.pinnacle.space.output_geometry(&first_op).unwrap();
|
||||
let third_geo = state.pinnacle.space.output_geometry(&third_op).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
original_geo,
|
||||
|
|
|
@ -46,11 +46,11 @@ pub(crate) fn run(channel: Channel<WlcsEvent>) {
|
|||
|
||||
// when xdiplay is None when starting the config, the grpc server is not
|
||||
// started, until it is set; this bypasses this for now
|
||||
state.xdisplay = Some(u32::MAX);
|
||||
state.pinnacle.xdisplay = Some(u32::MAX);
|
||||
run_config(&mut state);
|
||||
|
||||
// wait for the config to connect to the layout service
|
||||
while state.layout_state.layout_request_sender.is_none() {
|
||||
while state.pinnacle.layout_state.layout_request_sender.is_none() {
|
||||
event_loop
|
||||
.dispatch(Some(Duration::from_millis(10)), &mut state)
|
||||
.expect("event_loop error while waiting for config");
|
||||
|
@ -60,10 +60,11 @@ pub(crate) fn run(channel: Channel<WlcsEvent>) {
|
|||
.run(None, &mut state, |state| {
|
||||
state.update_pointer_focus();
|
||||
state.fixup_z_layering();
|
||||
state.space.refresh();
|
||||
state.popup_manager.cleanup();
|
||||
state.pinnacle.space.refresh();
|
||||
state.pinnacle.popup_manager.cleanup();
|
||||
|
||||
state
|
||||
.pinnacle
|
||||
.display_handle
|
||||
.flush_clients()
|
||||
.expect("failed to flush client buffers");
|
||||
|
@ -77,6 +78,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
WlcsEvent::Stop => state.shutdown(),
|
||||
WlcsEvent::NewClient { stream, client_id } => {
|
||||
let client: Client = state
|
||||
.pinnacle
|
||||
.display_handle
|
||||
.insert_client(stream, Arc::new(ClientState::default()))
|
||||
.expect("failed to insert new client");
|
||||
|
@ -89,11 +91,18 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
} => {
|
||||
let client = state.backend.wlcs_mut().clients.get(&client_id);
|
||||
let window = state
|
||||
.pinnacle
|
||||
.space
|
||||
.elements()
|
||||
.find(|w| {
|
||||
if let Some(surface) = w.wl_surface() {
|
||||
state.display_handle.get_client(surface.id()).ok().as_ref() == client
|
||||
state
|
||||
.pinnacle
|
||||
.display_handle
|
||||
.get_client(surface.id())
|
||||
.ok()
|
||||
.as_ref()
|
||||
== client
|
||||
&& surface.id().protocol_id() == surface_id
|
||||
} else {
|
||||
false
|
||||
|
@ -102,9 +111,13 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
.cloned();
|
||||
|
||||
if let Some(window) = window {
|
||||
state.space.map_element(window.clone(), location, false);
|
||||
state
|
||||
.pinnacle
|
||||
.space
|
||||
.map_element(window.clone(), location, false);
|
||||
|
||||
let size = state
|
||||
.pinnacle
|
||||
.space
|
||||
.element_geometry(&window)
|
||||
.expect("window to be positioned was not mapped")
|
||||
|
@ -119,7 +132,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
FloatingOrTiled::Floating(Rectangle::from_loc_and_size(location, size));
|
||||
});
|
||||
|
||||
for output in state.space.outputs_for_element(&window) {
|
||||
for output in state.pinnacle.space.outputs_for_element(&window) {
|
||||
state.schedule_render(&output);
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +152,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
} => state.process_input_event(
|
||||
WlcsPointerMotionAbsoluteEvent {
|
||||
device_id,
|
||||
time: Duration::from(state.clock.now()).as_millis() as u64,
|
||||
time: Duration::from(state.pinnacle.clock.now()).as_millis() as u64,
|
||||
position,
|
||||
}
|
||||
.into(),
|
||||
|
@ -147,7 +160,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
WlcsEvent::PointerMoveRelative { device_id, delta } => state.process_input_event(
|
||||
WlcsPointerMotionEvent {
|
||||
device_id,
|
||||
time: Duration::from(state.clock.now()).as_millis() as u64,
|
||||
time: Duration::from(state.pinnacle.clock.now()).as_millis() as u64,
|
||||
delta,
|
||||
}
|
||||
.into(),
|
||||
|
@ -159,7 +172,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
} => state.process_input_event(
|
||||
WlcsPointerButtonEvent {
|
||||
device_id,
|
||||
time: Duration::from(state.clock.now()).as_millis() as u64,
|
||||
time: Duration::from(state.pinnacle.clock.now()).as_millis() as u64,
|
||||
button_code: button_id as u32,
|
||||
state: if pressed {
|
||||
ButtonState::Pressed
|
||||
|
@ -183,7 +196,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
} => state.process_input_event(
|
||||
WlcsTouchDownEvent {
|
||||
device_id,
|
||||
time: Duration::from(state.clock.now()).as_millis() as u64,
|
||||
time: Duration::from(state.pinnacle.clock.now()).as_millis() as u64,
|
||||
position,
|
||||
}
|
||||
.into(),
|
||||
|
@ -194,7 +207,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
} => state.process_input_event(
|
||||
WlcsTouchDownEvent {
|
||||
device_id,
|
||||
time: Duration::from(state.clock.now()).as_millis() as u64,
|
||||
time: Duration::from(state.pinnacle.clock.now()).as_millis() as u64,
|
||||
position,
|
||||
}
|
||||
.into(),
|
||||
|
@ -202,7 +215,7 @@ fn handle_event(event: WlcsEvent, state: &mut State) {
|
|||
WlcsEvent::TouchUp { device_id } => state.process_input_event(
|
||||
WlcsTouchUpEvent {
|
||||
device_id,
|
||||
time: Duration::from(state.clock.now()).as_millis() as u64,
|
||||
time: Duration::from(state.pinnacle.clock.now()).as_millis() as u64,
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
|
|
Loading…
Add table
Reference in a new issue