mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Merge pull request #63 from Ottatop/fix_reappear
Fix windows not reappearing if their size isn't changed
This commit is contained in:
commit
6d3c6e2c62
4 changed files with 133 additions and 103 deletions
|
@ -853,38 +853,6 @@ impl State {
|
|||
device_id: node,
|
||||
});
|
||||
|
||||
// Run any connected callbacks
|
||||
{
|
||||
let clone = output.clone();
|
||||
self.loop_handle.insert_idle(|data| {
|
||||
crate::state::schedule(
|
||||
data,
|
||||
|dt| dt.state.api_state.stream.is_some(),
|
||||
move |dt| {
|
||||
let stream = dt
|
||||
.state
|
||||
.api_state
|
||||
.stream
|
||||
.as_ref()
|
||||
.expect("Stream doesn't exist");
|
||||
let mut stream = stream.lock().expect("Couldn't lock stream");
|
||||
for callback_id in dt.state.output_callback_ids.iter() {
|
||||
crate::api::send_to_client(
|
||||
&mut stream,
|
||||
&OutgoingMsg::CallCallback {
|
||||
callback_id: *callback_id,
|
||||
args: Some(Args::ConnectForAllOutputs {
|
||||
output_name: clone.name(),
|
||||
}),
|
||||
},
|
||||
)
|
||||
.expect("Send to client failed");
|
||||
}
|
||||
},
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
let allocator = GbmAllocator::new(
|
||||
device.gbm.clone(),
|
||||
GbmBufferFlags::RENDERING | GbmBufferFlags::SCANOUT,
|
||||
|
@ -980,6 +948,35 @@ impl State {
|
|||
device.surfaces.insert(crtc, surface);
|
||||
|
||||
self.schedule_initial_render(node, crtc, self.loop_handle.clone());
|
||||
|
||||
// Run any connected callbacks
|
||||
{
|
||||
let clone = output.clone();
|
||||
self.schedule(
|
||||
|dt| dt.state.api_state.stream.is_some(),
|
||||
move |dt| {
|
||||
let stream = dt
|
||||
.state
|
||||
.api_state
|
||||
.stream
|
||||
.as_ref()
|
||||
.expect("Stream doesn't exist");
|
||||
let mut stream = stream.lock().expect("Couldn't lock stream");
|
||||
for callback_id in dt.state.output_callback_ids.iter() {
|
||||
crate::api::send_to_client(
|
||||
&mut stream,
|
||||
&OutgoingMsg::CallCallback {
|
||||
callback_id: *callback_id,
|
||||
args: Some(Args::ConnectForAllOutputs {
|
||||
output_name: clone.name(),
|
||||
}),
|
||||
},
|
||||
)
|
||||
.expect("Send to client failed");
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn connector_disconnected(
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use smithay::{
|
||||
delegate_xdg_shell,
|
||||
desktop::{
|
||||
find_popup_root_surface, layer_map_for_output, utils::surface_primary_scanout_output,
|
||||
PopupKeyboardGrab, PopupKind, PopupPointerGrab, PopupUngrabStrategy, Window,
|
||||
WindowSurfaceType,
|
||||
find_popup_root_surface, layer_map_for_output, PopupKeyboardGrab, PopupKind,
|
||||
PopupPointerGrab, PopupUngrabStrategy, Window, WindowSurfaceType,
|
||||
},
|
||||
input::{pointer::Focus, Seat},
|
||||
output::Output,
|
||||
|
@ -91,49 +88,74 @@ impl XdgShellHandler for State {
|
|||
// note to self: don't reorder this
|
||||
// TODO: fix it so that reordering this doesn't break stuff
|
||||
self.windows.push(window.clone());
|
||||
// self.space.map_element(window.clone(), (0, 0), true);
|
||||
if let Some(focused_output) = self.focus_state.focused_output.clone() {
|
||||
self.update_windows(&focused_output);
|
||||
BLOCKER_COUNTER.store(1, std::sync::atomic::Ordering::SeqCst);
|
||||
tracing::debug!(
|
||||
"blocker {}",
|
||||
BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
||||
);
|
||||
for win in windows_on_output.iter() {
|
||||
if let Some(surf) = win.wl_surface() {
|
||||
compositor::add_blocker(&surf, crate::window::WindowBlocker);
|
||||
|
||||
self.space.map_element(window.clone(), (0, 0), true);
|
||||
|
||||
let win_clone = window.clone();
|
||||
self.schedule(
|
||||
move |_data| {
|
||||
if let WindowElement::Wayland(window) = &win_clone {
|
||||
let initial_configure_sent =
|
||||
compositor::with_states(window.toplevel().wl_surface(), |states| {
|
||||
states
|
||||
.data_map
|
||||
.get::<smithay::wayland::shell::xdg::XdgToplevelSurfaceData>()
|
||||
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
|
||||
.lock()
|
||||
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
|
||||
.initial_configure_sent
|
||||
});
|
||||
|
||||
initial_configure_sent
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
let clone = window.clone();
|
||||
self.loop_handle.insert_idle(|data| {
|
||||
crate::state::schedule_on_commit(data, vec![clone], move |data| {
|
||||
BLOCKER_COUNTER.store(0, std::sync::atomic::Ordering::SeqCst);
|
||||
},
|
||||
|data| {
|
||||
if let Some(focused_output) = data.state.focus_state.focused_output.clone() {
|
||||
data.state.update_windows(&focused_output);
|
||||
BLOCKER_COUNTER.store(1, std::sync::atomic::Ordering::SeqCst);
|
||||
tracing::debug!(
|
||||
"blocker {}",
|
||||
BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
||||
);
|
||||
for client in windows_on_output
|
||||
.iter()
|
||||
.filter_map(|win| win.wl_surface()?.client())
|
||||
{
|
||||
data.state
|
||||
.client_compositor_state(&client)
|
||||
.blocker_cleared(&mut data.state, &data.display.handle())
|
||||
for win in windows_on_output.iter() {
|
||||
if let Some(surf) = win.wl_surface() {
|
||||
compositor::add_blocker(&surf, crate::window::WindowBlocker);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
self.loop_handle.insert_idle(move |data| {
|
||||
data.state
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard") // FIXME: actually handle error
|
||||
.set_focus(
|
||||
&mut data.state,
|
||||
Some(FocusTarget::Window(window)),
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
);
|
||||
});
|
||||
let clone = window.clone();
|
||||
data.state.loop_handle.insert_idle(|data| {
|
||||
crate::state::schedule_on_commit(data, vec![clone], move |data| {
|
||||
BLOCKER_COUNTER.store(0, std::sync::atomic::Ordering::SeqCst);
|
||||
tracing::debug!(
|
||||
"blocker {}",
|
||||
BLOCKER_COUNTER.load(std::sync::atomic::Ordering::SeqCst)
|
||||
);
|
||||
for client in windows_on_output
|
||||
.iter()
|
||||
.filter_map(|win| win.wl_surface()?.client())
|
||||
{
|
||||
data.state
|
||||
.client_compositor_state(&client)
|
||||
.blocker_cleared(&mut data.state, &data.display.handle())
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
data.state.loop_handle.insert_idle(move |data| {
|
||||
data.state
|
||||
.seat
|
||||
.get_keyboard()
|
||||
.expect("Seat had no keyboard") // FIXME: actually handle error
|
||||
.set_focus(
|
||||
&mut data.state,
|
||||
Some(FocusTarget::Window(window)),
|
||||
SERIAL_COUNTER.next_serial(),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn toplevel_destroyed(&mut self, surface: ToplevelSurface) {
|
||||
|
@ -262,16 +284,6 @@ impl XdgShellHandler for State {
|
|||
// tracing::debug!("acked configure, new loc is {:?}", new_loc);
|
||||
state.loc_request_state =
|
||||
LocationRequestState::Acknowledged(new_loc);
|
||||
if let Some(focused_output) =
|
||||
self.focus_state.focused_output.clone()
|
||||
{
|
||||
window.send_frame(
|
||||
&focused_output,
|
||||
self.clock.now(),
|
||||
Some(Duration::ZERO),
|
||||
surface_primary_scanout_output,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Configure::Popup(_) => todo!(),
|
||||
|
|
|
@ -114,9 +114,17 @@ impl State {
|
|||
window.with_state(|state| {
|
||||
if let LocationRequestState::Sent(loc) = state.loc_request_state {
|
||||
match &window {
|
||||
WindowElement::Wayland(window) => {
|
||||
let serial = window.toplevel().send_configure();
|
||||
state.loc_request_state = LocationRequestState::Requested(serial, loc);
|
||||
WindowElement::Wayland(win) => {
|
||||
// If the above didn't cause any change to size or other state, simply
|
||||
// map the window.
|
||||
if !win.toplevel().has_pending_changes() {
|
||||
state.loc_request_state = LocationRequestState::Idle;
|
||||
self.space.map_element(window.clone(), loc, false);
|
||||
} else {
|
||||
let serial = win.toplevel().send_configure();
|
||||
state.loc_request_state =
|
||||
LocationRequestState::Requested(serial, loc);
|
||||
}
|
||||
}
|
||||
WindowElement::X11(surface) => {
|
||||
// already configured, just need to map
|
||||
|
|
45
src/state.rs
45
src/state.rs
|
@ -159,22 +159,6 @@ where
|
|||
on_commit(data);
|
||||
}
|
||||
|
||||
// Schedule something to be done when `condition` returns true.
|
||||
pub fn schedule<F1, F2>(data: &mut CalloopData, condition: F1, run: F2)
|
||||
where
|
||||
F1: Fn(&mut CalloopData) -> bool + 'static,
|
||||
F2: FnOnce(&mut CalloopData) + 'static,
|
||||
{
|
||||
if !condition(data) {
|
||||
data.state.loop_handle.insert_idle(|data| {
|
||||
schedule(data, condition, run);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
run(data);
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn init(
|
||||
backend: Backend,
|
||||
|
@ -393,6 +377,35 @@ impl State {
|
|||
xdisplay: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Schedule `run` to run when `condition` returns true.
|
||||
///
|
||||
/// This will continually reschedule `run` in the event loop if `condition` returns false.
|
||||
pub fn schedule<F1, F2>(&self, condition: F1, run: F2)
|
||||
where
|
||||
F1: Fn(&mut CalloopData) -> bool + 'static,
|
||||
F2: FnOnce(&mut CalloopData) + 'static,
|
||||
{
|
||||
self.loop_handle.insert_idle(|data| {
|
||||
Self::schedule_inner(data, condition, run);
|
||||
});
|
||||
}
|
||||
|
||||
// Schedule something to be done when `condition` returns true.
|
||||
fn schedule_inner<F1, F2>(data: &mut CalloopData, condition: F1, run: F2)
|
||||
where
|
||||
F1: Fn(&mut CalloopData) -> bool + 'static,
|
||||
F2: FnOnce(&mut CalloopData) + 'static,
|
||||
{
|
||||
if !condition(data) {
|
||||
data.state.loop_handle.insert_idle(|data| {
|
||||
Self::schedule_inner(data, condition, run);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
run(data);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_config_dir() -> PathBuf {
|
||||
|
|
Loading…
Reference in a new issue