mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-27 21:58:18 +01:00
Fix x11 windows not removing when destroyed
This commit is contained in:
parent
f92153eb04
commit
c2190f2e0c
5 changed files with 190 additions and 196 deletions
|
@ -76,63 +76,63 @@ require("pinnacle").setup(function(pinnacle)
|
||||||
end
|
end
|
||||||
|
|
||||||
print("----------------------")
|
print("----------------------")
|
||||||
|
--
|
||||||
local op = output.get_focused() --[[@as Output]]
|
-- local op = output.get_focused() --[[@as Output]]
|
||||||
print("res: " .. (op:res() and (op:res().w .. ", " .. op:res().h) or "nil"))
|
-- print("res: " .. (op:res() and (op:res().w .. ", " .. op:res().h) or "nil"))
|
||||||
print("loc: " .. (op:loc() and (op:loc().x .. ", " .. op:loc().y) or "nil"))
|
-- print("loc: " .. (op:loc() and (op:loc().x .. ", " .. op:loc().y) or "nil"))
|
||||||
print("rr: " .. (op:refresh_rate() or "nil"))
|
-- print("rr: " .. (op:refresh_rate() or "nil"))
|
||||||
print("make: " .. (op:make() or "nil"))
|
-- print("make: " .. (op:make() or "nil"))
|
||||||
print("model: " .. (op:model() or "nil"))
|
-- print("model: " .. (op:model() or "nil"))
|
||||||
print("focused: " .. (tostring(op:focused())))
|
-- print("focused: " .. (tostring(op:focused())))
|
||||||
|
--
|
||||||
print("----------------------")
|
-- print("----------------------")
|
||||||
|
--
|
||||||
local wins = window.get_by_class("Alacritty")
|
-- local wins = window.get_by_class("Alacritty")
|
||||||
for _, win in pairs(wins) do
|
-- for _, win in pairs(wins) do
|
||||||
print("loc: " .. (win:loc() and win:loc().x or "nil") .. ", " .. (win:loc() and win:loc().y or "nil"))
|
-- print("loc: " .. (win:loc() and win:loc().x or "nil") .. ", " .. (win:loc() and win:loc().y or "nil"))
|
||||||
print("size: " .. (win:size() and win:size().w or "nil") .. ", " .. (win:size() and win:size().h or "nil"))
|
-- print("size: " .. (win:size() and win:size().w or "nil") .. ", " .. (win:size() and win:size().h or "nil"))
|
||||||
print("class: " .. (win:class() or "nil"))
|
-- print("class: " .. (win:class() or "nil"))
|
||||||
print("title: " .. (win:title() or "nil"))
|
-- print("title: " .. (win:title() or "nil"))
|
||||||
print("float: " .. tostring(win:floating()))
|
-- print("float: " .. tostring(win:floating()))
|
||||||
end
|
-- end
|
||||||
|
--
|
||||||
print("----------------------")
|
-- print("----------------------")
|
||||||
|
--
|
||||||
local wins = window.get_by_title("~/p/pinnacle")
|
-- local wins = window.get_by_title("~/p/pinnacle")
|
||||||
for _, win in pairs(wins) do
|
-- for _, win in pairs(wins) do
|
||||||
print("loc: " .. (win:loc() and win:loc().x or "nil") .. ", " .. (win:loc() and win:loc().y or "nil"))
|
-- print("loc: " .. (win:loc() and win:loc().x or "nil") .. ", " .. (win:loc() and win:loc().y or "nil"))
|
||||||
print("size: " .. (win:size() and win:size().w or "nil") .. ", " .. (win:size() and win:size().h or "nil"))
|
-- print("size: " .. (win:size() and win:size().w or "nil") .. ", " .. (win:size() and win:size().h or "nil"))
|
||||||
print("class: " .. (win:class() or "nil"))
|
-- print("class: " .. (win:class() or "nil"))
|
||||||
print("title: " .. (win:title() or "nil"))
|
-- print("title: " .. (win:title() or "nil"))
|
||||||
print("float: " .. tostring(win:floating()))
|
-- print("float: " .. tostring(win:floating()))
|
||||||
end
|
-- end
|
||||||
|
--
|
||||||
print("----------------------")
|
-- print("----------------------")
|
||||||
|
--
|
||||||
local tags = tag.get_on_output(output.get_focused() --[[@as Output]])
|
-- local tags = tag.get_on_output(output.get_focused() --[[@as Output]])
|
||||||
for _, tg in pairs(tags) do
|
-- for _, tg in pairs(tags) do
|
||||||
print(tg:name())
|
-- print(tg:name())
|
||||||
print((tg:output() and tg:output():name()) or "nil output")
|
-- print((tg:output() and tg:output():name()) or "nil output")
|
||||||
print(tg:active())
|
-- print(tg:active())
|
||||||
end
|
-- end
|
||||||
|
--
|
||||||
print("----------------------")
|
-- print("----------------------")
|
||||||
|
--
|
||||||
local tags = tag.get_by_name("2")
|
-- local tags = tag.get_by_name("2")
|
||||||
for _, tg in pairs(tags) do
|
-- for _, tg in pairs(tags) do
|
||||||
print(tg:name())
|
-- print(tg:name())
|
||||||
print((tg:output() and tg:output():name()) or "nil output")
|
-- print((tg:output() and tg:output():name()) or "nil output")
|
||||||
print(tg:active())
|
-- print(tg:active())
|
||||||
end
|
-- end
|
||||||
|
--
|
||||||
print("----------------------")
|
-- print("----------------------")
|
||||||
|
--
|
||||||
local tags = tag.get_all()
|
-- local tags = tag.get_all()
|
||||||
for _, tg in pairs(tags) do
|
-- for _, tg in pairs(tags) do
|
||||||
print(tg:name())
|
-- print(tg:name())
|
||||||
print((tg:output() and tg:output():name()) or "nil output")
|
-- print((tg:output() and tg:output():name()) or "nil output")
|
||||||
print(tg:active())
|
-- print(tg:active())
|
||||||
end
|
-- end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Tags ---------------------------------------------------------------------------
|
-- Tags ---------------------------------------------------------------------------
|
||||||
|
@ -211,146 +211,67 @@ require("pinnacle").setup(function(pinnacle)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
input.keybind({ mod_key }, keys.KEY_1, function()
|
input.keybind({ mod_key }, keys.KEY_1, function()
|
||||||
for _, t in pairs(tag.get_by_name("1")) do
|
tag.switch_to("1")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:switch_to()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key }, keys.KEY_2, function()
|
input.keybind({ mod_key }, keys.KEY_2, function()
|
||||||
for _, t in pairs(tag.get_by_name("2")) do
|
tag.switch_to("2")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:switch_to()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key }, keys.KEY_3, function()
|
input.keybind({ mod_key }, keys.KEY_3, function()
|
||||||
for _, t in pairs(tag.get_by_name("3")) do
|
tag.switch_to("3")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:switch_to()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key }, keys.KEY_4, function()
|
input.keybind({ mod_key }, keys.KEY_4, function()
|
||||||
for _, t in pairs(tag.get_by_name("4")) do
|
tag.switch_to("4")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:switch_to()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key }, keys.KEY_5, function()
|
input.keybind({ mod_key }, keys.KEY_5, function()
|
||||||
for _, t in pairs(tag.get_by_name("5")) do
|
tag.switch_to("5")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:switch_to()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
input.keybind({ mod_key, "Shift" }, keys.KEY_1, function()
|
input.keybind({ mod_key, "Shift" }, keys.KEY_1, function()
|
||||||
for _, t in pairs(tag.get_by_name("1")) do
|
tag.toggle("1")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:toggle()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift" }, keys.KEY_2, function()
|
input.keybind({ mod_key, "Shift" }, keys.KEY_2, function()
|
||||||
for _, t in pairs(tag.get_by_name("2")) do
|
tag.toggle("2")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:toggle()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift" }, keys.KEY_3, function()
|
input.keybind({ mod_key, "Shift" }, keys.KEY_3, function()
|
||||||
for _, t in pairs(tag.get_by_name("3")) do
|
tag.toggle("3")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:toggle()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift" }, keys.KEY_4, function()
|
input.keybind({ mod_key, "Shift" }, keys.KEY_4, function()
|
||||||
for _, t in pairs(tag.get_by_name("4")) do
|
tag.toggle("4")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:toggle()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift" }, keys.KEY_5, function()
|
input.keybind({ mod_key, "Shift" }, keys.KEY_5, function()
|
||||||
for _, t in pairs(tag.get_by_name("5")) do
|
tag.toggle("5")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
t:toggle()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- I check for nil this way because I don't want stylua to take up like 80 lines on `if win ~= nil`
|
||||||
input.keybind({ mod_key, "Alt" }, keys.KEY_1, function()
|
input.keybind({ mod_key, "Alt" }, keys.KEY_1, function()
|
||||||
for _, t in pairs(tag.get_by_name("1")) do
|
local _ = window.get_focused() and window:get_focused():move_to_tag("1")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():move_to_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Alt" }, keys.KEY_2, function()
|
input.keybind({ mod_key, "Alt" }, keys.KEY_2, function()
|
||||||
for _, t in pairs(tag.get_by_name("2")) do
|
local _ = window.get_focused() and window:get_focused():move_to_tag("2")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():move_to_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Alt" }, keys.KEY_3, function()
|
input.keybind({ mod_key, "Alt" }, keys.KEY_3, function()
|
||||||
for _, t in pairs(tag.get_by_name("3")) do
|
local _ = window.get_focused() and window:get_focused():move_to_tag("3")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():move_to_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Alt" }, keys.KEY_4, function()
|
input.keybind({ mod_key, "Alt" }, keys.KEY_4, function()
|
||||||
for _, t in pairs(tag.get_by_name("4")) do
|
local _ = window.get_focused() and window:get_focused():move_to_tag("4")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():move_to_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Alt" }, keys.KEY_5, function()
|
input.keybind({ mod_key, "Alt" }, keys.KEY_5, function()
|
||||||
for _, t in pairs(tag.get_by_name("5")) do
|
local _ = window.get_focused() and window:get_focused():move_to_tag("5")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():move_to_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_1, function()
|
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_1, function()
|
||||||
for _, t in pairs(tag.get_by_name("1")) do
|
local _ = window.get_focused() and window.get_focused():toggle_tag("1")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():toggle_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_2, function()
|
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_2, function()
|
||||||
for _, t in pairs(tag.get_by_name("2")) do
|
local _ = window.get_focused() and window.get_focused():toggle_tag("2")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():toggle_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_3, function()
|
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_3, function()
|
||||||
for _, t in pairs(tag.get_by_name("3")) do
|
local _ = window.get_focused() and window.get_focused():toggle_tag("3")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():toggle_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_4, function()
|
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_4, function()
|
||||||
for _, t in pairs(tag.get_by_name("4")) do
|
local _ = window.get_focused() and window.get_focused():toggle_tag("4")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():toggle_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_5, function()
|
input.keybind({ mod_key, "Shift", "Alt" }, keys.KEY_5, function()
|
||||||
for _, t in pairs(tag.get_by_name("5")) do
|
local _ = window.get_focused() and window.get_focused():toggle_tag("5")
|
||||||
if t:output() and t:output():focused() then
|
|
||||||
window.get_focused():toggle_tag(t)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -8,9 +8,12 @@ use smithay::{
|
||||||
desktop::space::SpaceElement,
|
desktop::space::SpaceElement,
|
||||||
input::pointer::Focus,
|
input::pointer::Focus,
|
||||||
reexports::wayland_server::Resource,
|
reexports::wayland_server::Resource,
|
||||||
utils::{Rectangle, SERIAL_COUNTER},
|
utils::{Logical, Rectangle, SERIAL_COUNTER},
|
||||||
wayland::compositor::{self, CompositorHandler},
|
wayland::compositor::{self, CompositorHandler},
|
||||||
xwayland::{xwm::XwmId, X11Wm, XwmHandler},
|
xwayland::{
|
||||||
|
xwm::{Reorder, XwmId},
|
||||||
|
X11Surface, X11Wm, XwmHandler,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -25,11 +28,11 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
self.state.xwm.as_mut().expect("xwm not in state")
|
self.state.xwm.as_mut().expect("xwm not in state")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_window(&mut self, xwm: XwmId, window: smithay::xwayland::X11Surface) {}
|
fn new_window(&mut self, xwm: XwmId, window: X11Surface) {}
|
||||||
|
|
||||||
fn new_override_redirect_window(&mut self, xwm: XwmId, window: smithay::xwayland::X11Surface) {}
|
fn new_override_redirect_window(&mut self, xwm: XwmId, window: X11Surface) {}
|
||||||
|
|
||||||
fn map_window_request(&mut self, xwm: XwmId, window: smithay::xwayland::X11Surface) {
|
fn map_window_request(&mut self, xwm: XwmId, window: X11Surface) {
|
||||||
tracing::debug!("new x11 window from map_window_request");
|
tracing::debug!("new x11 window from map_window_request");
|
||||||
window.set_mapped(true).expect("failed to map x11 window");
|
window.set_mapped(true).expect("failed to map x11 window");
|
||||||
let window = WindowElement::X11(window);
|
let window = WindowElement::X11(window);
|
||||||
|
@ -149,17 +152,14 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mapped_override_redirect_window(
|
fn mapped_override_redirect_window(&mut self, xwm: XwmId, window: X11Surface) {
|
||||||
&mut self,
|
|
||||||
xwm: XwmId,
|
|
||||||
window: smithay::xwayland::X11Surface,
|
|
||||||
) {
|
|
||||||
let loc = window.geometry().loc;
|
let loc = window.geometry().loc;
|
||||||
let window = WindowElement::X11(window);
|
let window = WindowElement::X11(window);
|
||||||
self.state.space.map_element(window, loc, true);
|
self.state.space.map_element(window, loc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmapped_window(&mut self, xwm: XwmId, window: smithay::xwayland::X11Surface) {
|
fn unmapped_window(&mut self, xwm: XwmId, window: X11Surface) {
|
||||||
|
tracing::debug!("unmapped x11 window");
|
||||||
let win = self
|
let win = self
|
||||||
.state
|
.state
|
||||||
.space
|
.space
|
||||||
|
@ -168,23 +168,50 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
.cloned();
|
.cloned();
|
||||||
if let Some(win) = win {
|
if let Some(win) = win {
|
||||||
self.state.space.unmap_elem(&win);
|
self.state.space.unmap_elem(&win);
|
||||||
|
// self.state.windows.retain(|elem| &win != elem);
|
||||||
|
if win.with_state(|state| state.floating.is_tiled()) {
|
||||||
|
if let Some(output) = win.output(&self.state) {
|
||||||
|
self.state.re_layout(&output);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !window.is_override_redirect() {
|
if !window.is_override_redirect() {
|
||||||
window.set_mapped(false).expect("failed to unmap x11 win");
|
window.set_mapped(false).expect("failed to unmap x11 win");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroyed_window(&mut self, xwm: XwmId, window: smithay::xwayland::X11Surface) {}
|
fn destroyed_window(&mut self, xwm: XwmId, window: X11Surface) {
|
||||||
|
let win = self
|
||||||
|
.state
|
||||||
|
.windows
|
||||||
|
.iter()
|
||||||
|
.find(|elem| {
|
||||||
|
matches!(elem,
|
||||||
|
WindowElement::X11(surface) if surface.wl_surface() == window.wl_surface())
|
||||||
|
})
|
||||||
|
.cloned();
|
||||||
|
tracing::debug!("{win:?}");
|
||||||
|
if let Some(win) = win {
|
||||||
|
tracing::debug!("removing x11 window from windows");
|
||||||
|
self.state.windows.retain(|elem| win.wl_surface() != elem.wl_surface());
|
||||||
|
if win.with_state(|state| state.floating.is_tiled()) {
|
||||||
|
if let Some(output) = win.output(&self.state) {
|
||||||
|
self.state.re_layout(&output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tracing::debug!("destroyed x11 window");
|
||||||
|
}
|
||||||
|
|
||||||
fn configure_request(
|
fn configure_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
xwm: XwmId,
|
xwm: XwmId,
|
||||||
window: smithay::xwayland::X11Surface,
|
window: X11Surface,
|
||||||
x: Option<i32>,
|
x: Option<i32>,
|
||||||
y: Option<i32>,
|
y: Option<i32>,
|
||||||
w: Option<u32>,
|
w: Option<u32>,
|
||||||
h: Option<u32>,
|
h: Option<u32>,
|
||||||
reorder: Option<smithay::xwayland::xwm::Reorder>,
|
reorder: Option<Reorder>,
|
||||||
) {
|
) {
|
||||||
let mut geo = window.geometry();
|
let mut geo = window.geometry();
|
||||||
if let Some(w) = w {
|
if let Some(w) = w {
|
||||||
|
@ -201,8 +228,8 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
fn configure_notify(
|
fn configure_notify(
|
||||||
&mut self,
|
&mut self,
|
||||||
xwm: XwmId,
|
xwm: XwmId,
|
||||||
window: smithay::xwayland::X11Surface,
|
window: X11Surface,
|
||||||
geometry: smithay::utils::Rectangle<i32, smithay::utils::Logical>,
|
geometry: Rectangle<i32, Logical>,
|
||||||
above: Option<smithay::reexports::x11rb::protocol::xproto::Window>,
|
above: Option<smithay::reexports::x11rb::protocol::xproto::Window>,
|
||||||
) {
|
) {
|
||||||
let Some(win) = self
|
let Some(win) = self
|
||||||
|
@ -229,7 +256,7 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
fn resize_request(
|
fn resize_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
xwm: XwmId,
|
xwm: XwmId,
|
||||||
window: smithay::xwayland::X11Surface,
|
window: X11Surface,
|
||||||
button: u32,
|
button: u32,
|
||||||
resize_edge: smithay::xwayland::xwm::ResizeEdge,
|
resize_edge: smithay::xwayland::xwm::ResizeEdge,
|
||||||
) {
|
) {
|
||||||
|
@ -283,8 +310,8 @@ impl<B: Backend> XwmHandler for CalloopData<B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_request(&mut self, xwm: XwmId, window: smithay::xwayland::X11Surface, button: u32) {
|
fn move_request(&mut self, xwm: XwmId, window: X11Surface, button: u32) {
|
||||||
todo!()
|
// TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: allow_selection_access
|
// TODO: allow_selection_access
|
||||||
|
|
39
src/state.rs
39
src/state.rs
|
@ -47,7 +47,7 @@ use smithay::{
|
||||||
Display,
|
Display,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
utils::{Clock, Logical, Monotonic, Point, Size},
|
utils::{Clock, IsAlive, Logical, Monotonic, Point, Size},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{self, CompositorClientState, CompositorState},
|
compositor::{self, CompositorClientState, CompositorState},
|
||||||
data_device::DataDeviceState,
|
data_device::DataDeviceState,
|
||||||
|
@ -305,20 +305,24 @@ impl<B: Backend> State<B> {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|win| self.space.element_location(win))
|
.and_then(|win| self.space.element_location(win))
|
||||||
.map(|loc| (loc.x, loc.y));
|
.map(|loc| (loc.x, loc.y));
|
||||||
let (class, title) = window.as_ref().and_then(|win| win.wl_surface()).map_or(
|
let (class, title) = window.as_ref().map_or((None, None), |win| match &win {
|
||||||
(None, None),
|
WindowElement::Wayland(_) => {
|
||||||
|wl_surf| {
|
if let Some(wl_surf) = win.wl_surface() {
|
||||||
compositor::with_states(&wl_surf, |states| {
|
compositor::with_states(&wl_surf, |states| {
|
||||||
let lock = states
|
let lock = states
|
||||||
.data_map
|
.data_map
|
||||||
.get::<XdgToplevelSurfaceData>()
|
.get::<XdgToplevelSurfaceData>()
|
||||||
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
|
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
|
||||||
.lock()
|
.lock()
|
||||||
.expect("failed to acquire lock");
|
.expect("failed to acquire lock");
|
||||||
(lock.app_id.clone(), lock.title.clone())
|
(lock.app_id.clone(), lock.title.clone())
|
||||||
})
|
})
|
||||||
},
|
} else {
|
||||||
);
|
(None, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WindowElement::X11(surface) => (Some(surface.class()), Some(surface.title())),
|
||||||
|
});
|
||||||
let floating = window
|
let floating = window
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|win| win.with_state(|state| state.floating.is_floating()));
|
.map(|win| win.with_state(|state| state.floating.is_floating()));
|
||||||
|
@ -619,6 +623,11 @@ impl<B: Backend> State<B> {
|
||||||
.any(|tag| tag.output(self).is_some_and(|op| &op == output))
|
.any(|tag| tag.output(self).is_some_and(|op| &op == output))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.filter(|win| match win {
|
||||||
|
WindowElement::Wayland(win) => !win.with_state(|state| state.minimized),
|
||||||
|
WindowElement::X11(surf) => !surf.is_minimized(),
|
||||||
|
})
|
||||||
|
.filter(|win| win.alive())
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let (render, do_not_render) = output.with_state(|state| {
|
let (render, do_not_render) = output.with_state(|state| {
|
||||||
|
|
|
@ -40,7 +40,7 @@ use crate::{
|
||||||
state::{State, WithState},
|
state::{State, WithState},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::window_state::{Float, WindowResizeState, WindowState};
|
use self::window_state::{Float, WindowElementState, WindowResizeState};
|
||||||
|
|
||||||
pub mod window_state;
|
pub mod window_state;
|
||||||
|
|
||||||
|
@ -202,6 +202,13 @@ impl WindowElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the output this window is on.
|
||||||
|
///
|
||||||
|
/// This method gets the first tag the window has and returns its output.
|
||||||
|
pub fn output<B: Backend>(&self, state: &State<B>) -> Option<Output> {
|
||||||
|
self.with_state(|st| st.tags.first().and_then(|tag| tag.output(state)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsAlive for WindowElement {
|
impl IsAlive for WindowElement {
|
||||||
|
@ -401,7 +408,7 @@ impl SpaceElement for WindowElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WithState for WindowElement {
|
impl WithState for WindowElement {
|
||||||
type State = WindowState;
|
type State = WindowElementState;
|
||||||
|
|
||||||
fn with_state<F, T>(&self, mut func: F) -> T
|
fn with_state<F, T>(&self, mut func: F) -> T
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
fmt,
|
fmt,
|
||||||
sync::atomic::{AtomicU32, Ordering},
|
sync::atomic::{AtomicU32, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use smithay::utils::{Logical, Point, Serial, Size};
|
use smithay::{
|
||||||
|
desktop::Window,
|
||||||
|
utils::{Logical, Point, Serial, Size},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::Backend,
|
backend::Backend,
|
||||||
|
@ -35,7 +39,32 @@ impl WindowId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
pub struct WindowState {
|
pub struct WindowState {
|
||||||
|
pub minimized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithState for Window {
|
||||||
|
type State = WindowState;
|
||||||
|
|
||||||
|
fn with_state<F, T>(&self, mut func: F) -> T
|
||||||
|
where
|
||||||
|
F: FnMut(&mut Self::State) -> T,
|
||||||
|
{
|
||||||
|
self.user_data()
|
||||||
|
.insert_if_missing(RefCell::<Self::State>::default);
|
||||||
|
|
||||||
|
let state = self
|
||||||
|
.user_data()
|
||||||
|
.get::<RefCell<Self::State>>()
|
||||||
|
.expect("RefCell not in data map");
|
||||||
|
|
||||||
|
func(&mut state.borrow_mut())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct WindowElementState {
|
||||||
/// The id of this window.
|
/// The id of this window.
|
||||||
pub id: WindowId,
|
pub id: WindowId,
|
||||||
/// Whether the window is floating or tiled.
|
/// Whether the window is floating or tiled.
|
||||||
|
@ -95,6 +124,7 @@ impl fmt::Debug for WindowResizeState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Float {
|
pub enum Float {
|
||||||
/// The previous location and size of the window when it was floating, if any.
|
/// The previous location and size of the window when it was floating, if any.
|
||||||
Tiled(Option<(Point<i32, Logical>, Size<i32, Logical>)>),
|
Tiled(Option<(Point<i32, Logical>, Size<i32, Logical>)>),
|
||||||
|
@ -119,14 +149,14 @@ impl Float {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowState {
|
impl WindowElementState {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WindowState {
|
impl Default for WindowElementState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
// INFO: I think this will assign the id on use of the state, not on window spawn.
|
// INFO: I think this will assign the id on use of the state, not on window spawn.
|
||||||
|
|
Loading…
Reference in a new issue