server: split XConnection from rest of State refactor
This commit is contained in:
parent
ecbe57e7be
commit
56d5cce2d0
5 changed files with 432 additions and 255 deletions
|
|
@ -54,7 +54,7 @@ pub fn main(mut data: impl RunData) -> Option<()> {
|
||||||
info!("Starting xwayland-satellite version {version}");
|
info!("Starting xwayland-satellite version {version}");
|
||||||
|
|
||||||
let socket = ListeningSocket::bind_auto("xwls", 1..=128).unwrap();
|
let socket = ListeningSocket::bind_auto("xwls", 1..=128).unwrap();
|
||||||
let mut display = Display::<RealServerState>::new().unwrap();
|
let mut display = Display::new().unwrap();
|
||||||
let dh = display.handle();
|
let dh = display.handle();
|
||||||
data.created_server();
|
data.created_server();
|
||||||
|
|
||||||
|
|
@ -203,7 +203,7 @@ pub fn main(mut data: impl RunData) -> Option<()> {
|
||||||
xstate.handle_events(&mut server_state);
|
xstate.handle_events(&mut server_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
display.dispatch_clients(&mut server_state).unwrap();
|
display.dispatch_clients(server_state.inner_mut()).unwrap();
|
||||||
server_state.run();
|
server_state.run();
|
||||||
display.flush_clients().unwrap();
|
display.flush_clients().unwrap();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ use wayland_server::{
|
||||||
};
|
};
|
||||||
|
|
||||||
// noop
|
// noop
|
||||||
impl<C: XConnection> Dispatch<WlCallback, ()> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlCallback, ()> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
_: &mut Self,
|
_: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -79,7 +79,7 @@ impl<C: XConnection> Dispatch<WlCallback, ()> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlSurface, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlSurface, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -182,7 +182,7 @@ impl<C: XConnection> Dispatch<WlSurface, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlRegion, client::wl_region::WlRegion> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlRegion, client::wl_region::WlRegion> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
_: &mut Self,
|
_: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -202,9 +202,9 @@ impl<C: XConnection> Dispatch<WlRegion, client::wl_region::WlRegion> for ServerS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection>
|
impl<S: X11Selection>
|
||||||
Dispatch<WlCompositor, ClientGlobalWrapper<client::wl_compositor::WlCompositor>>
|
Dispatch<WlCompositor, ClientGlobalWrapper<client::wl_compositor::WlCompositor>>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -251,7 +251,7 @@ impl<C: XConnection>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlBuffer, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlBuffer, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -272,7 +272,7 @@ impl<C: XConnection> Dispatch<WlBuffer, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlShmPool, client::wl_shm_pool::WlShmPool> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlShmPool, client::wl_shm_pool::WlShmPool> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -316,8 +316,8 @@ impl<C: XConnection> Dispatch<WlShmPool, client::wl_shm_pool::WlShmPool> for Ser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlShm, ClientGlobalWrapper<client::wl_shm::WlShm>>
|
impl<S: X11Selection> Dispatch<WlShm, ClientGlobalWrapper<client::wl_shm::WlShm>>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -340,7 +340,7 @@ impl<C: XConnection> Dispatch<WlShm, ClientGlobalWrapper<client::wl_shm::WlShm>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlPointer, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlPointer, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -383,7 +383,7 @@ impl<C: XConnection> Dispatch<WlPointer, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlKeyboard, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlKeyboard, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -407,7 +407,7 @@ impl<C: XConnection> Dispatch<WlKeyboard, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlTouch, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlTouch, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -431,7 +431,7 @@ impl<C: XConnection> Dispatch<WlTouch, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlSeat, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlSeat, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -484,7 +484,7 @@ impl<C: XConnection> Dispatch<WlSeat, Entity> for ServerState<C> {
|
||||||
|
|
||||||
macro_rules! only_destroy_request_impl {
|
macro_rules! only_destroy_request_impl {
|
||||||
($server:ty, $client:ty) => {
|
($server:ty, $client:ty) => {
|
||||||
impl<C: XConnection> Dispatch<$server, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<$server, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &Client,
|
_: &Client,
|
||||||
|
|
@ -512,9 +512,9 @@ macro_rules! only_destroy_request_impl {
|
||||||
|
|
||||||
only_destroy_request_impl!(RelativePointerServer, RelativePointerClient);
|
only_destroy_request_impl!(RelativePointerServer, RelativePointerClient);
|
||||||
|
|
||||||
impl<C: XConnection>
|
impl<S: X11Selection>
|
||||||
Dispatch<RelativePointerManServer, ClientGlobalWrapper<RelativePointerManClient>>
|
Dispatch<RelativePointerManServer, ClientGlobalWrapper<RelativePointerManClient>>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -545,7 +545,7 @@ impl<C: XConnection>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlOutput, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlOutput, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -569,9 +569,9 @@ impl<C: XConnection> Dispatch<WlOutput, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection>
|
impl<S: X11Selection>
|
||||||
Dispatch<s_dmabuf::zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1, Entity>
|
Dispatch<s_dmabuf::zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1, Entity>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -599,11 +599,11 @@ impl<C: XConnection>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection>
|
impl<S: X11Selection>
|
||||||
Dispatch<
|
Dispatch<
|
||||||
s_dmabuf::zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
|
s_dmabuf::zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
|
||||||
c_dmabuf::zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
|
c_dmabuf::zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1,
|
||||||
> for ServerState<C>
|
> for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -662,11 +662,11 @@ impl<C: XConnection>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection>
|
impl<S: X11Selection>
|
||||||
Dispatch<
|
Dispatch<
|
||||||
s_dmabuf::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
|
s_dmabuf::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
|
||||||
ClientGlobalWrapper<c_dmabuf::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>,
|
ClientGlobalWrapper<c_dmabuf::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>,
|
||||||
> for ServerState<C>
|
> for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -711,7 +711,7 @@ impl<C: XConnection>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<WlDrmServer, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<WlDrmServer, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -827,7 +827,7 @@ impl<C: XConnection> Dispatch<WlDrmServer, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<XdgOutputServer, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<XdgOutputServer, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -849,8 +849,8 @@ impl<C: XConnection> Dispatch<XdgOutputServer, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<OutputManServer, ClientGlobalWrapper<OutputManClient>>
|
impl<S: X11Selection> Dispatch<OutputManServer, ClientGlobalWrapper<OutputManClient>>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -880,7 +880,7 @@ impl<C: XConnection> Dispatch<OutputManServer, ClientGlobalWrapper<OutputManClie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<ConfinedPointerServer, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<ConfinedPointerServer, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -902,7 +902,7 @@ impl<C: XConnection> Dispatch<ConfinedPointerServer, Entity> for ServerState<C>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<LockedPointerServer, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<LockedPointerServer, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
@ -941,9 +941,9 @@ impl<C: XConnection> Dispatch<LockedPointerServer, Entity> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection>
|
impl<S: X11Selection>
|
||||||
Dispatch<PointerConstraintsServer, ClientGlobalWrapper<PointerConstraintsClient>>
|
Dispatch<PointerConstraintsServer, ClientGlobalWrapper<PointerConstraintsClient>>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -1039,11 +1039,11 @@ impl<C: XConnection>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection>
|
impl<S: X11Selection>
|
||||||
Dispatch<
|
Dispatch<
|
||||||
s_tablet::zwp_tablet_manager_v2::ZwpTabletManagerV2,
|
s_tablet::zwp_tablet_manager_v2::ZwpTabletManagerV2,
|
||||||
ClientGlobalWrapper<c_tablet::zwp_tablet_manager_v2::ZwpTabletManagerV2>,
|
ClientGlobalWrapper<c_tablet::zwp_tablet_manager_v2::ZwpTabletManagerV2>,
|
||||||
> for ServerState<C>
|
> for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -1091,8 +1091,8 @@ only_destroy_request_impl!(
|
||||||
c_tablet::zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2
|
c_tablet::zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<s_tablet::zwp_tablet_pad_v2::ZwpTabletPadV2, Entity>
|
impl<S: X11Selection> Dispatch<s_tablet::zwp_tablet_pad_v2::ZwpTabletPadV2, Entity>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -1125,8 +1125,8 @@ impl<C: XConnection> Dispatch<s_tablet::zwp_tablet_pad_v2::ZwpTabletPadV2, Entit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<s_tablet::zwp_tablet_tool_v2::ZwpTabletToolV2, Entity>
|
impl<S: X11Selection> Dispatch<s_tablet::zwp_tablet_tool_v2::ZwpTabletToolV2, Entity>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -1167,8 +1167,8 @@ impl<C: XConnection> Dispatch<s_tablet::zwp_tablet_tool_v2::ZwpTabletToolV2, Ent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<s_tablet::zwp_tablet_pad_ring_v2::ZwpTabletPadRingV2, Entity>
|
impl<S: X11Selection> Dispatch<s_tablet::zwp_tablet_pad_ring_v2::ZwpTabletPadRingV2, Entity>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -1200,8 +1200,8 @@ impl<C: XConnection> Dispatch<s_tablet::zwp_tablet_pad_ring_v2::ZwpTabletPadRing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<s_tablet::zwp_tablet_pad_strip_v2::ZwpTabletPadStripV2, Entity>
|
impl<S: X11Selection> Dispatch<s_tablet::zwp_tablet_pad_strip_v2::ZwpTabletPadStripV2, Entity>
|
||||||
for ServerState<C>
|
for InnerServerState<S>
|
||||||
{
|
{
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
|
|
@ -1251,9 +1251,9 @@ impl<T: Proxy> Default for ClientGlobalWrapper<T> {
|
||||||
|
|
||||||
macro_rules! global_dispatch_no_events {
|
macro_rules! global_dispatch_no_events {
|
||||||
($server:ty, $client:ty) => {
|
($server:ty, $client:ty) => {
|
||||||
impl<C: XConnection> GlobalDispatch<$server, Global> for ServerState<C>
|
impl<S: X11Selection> GlobalDispatch<$server, Global> for InnerServerState<S>
|
||||||
where
|
where
|
||||||
ServerState<C>: Dispatch<$server, ClientGlobalWrapper<$client>>,
|
InnerServerState<S>: Dispatch<$server, ClientGlobalWrapper<$client>>,
|
||||||
MyWorld: wayland_client::Dispatch<$client, ()>,
|
MyWorld: wayland_client::Dispatch<$client, ()>,
|
||||||
{
|
{
|
||||||
fn bind(
|
fn bind(
|
||||||
|
|
@ -1282,11 +1282,11 @@ macro_rules! global_dispatch_no_events {
|
||||||
|
|
||||||
macro_rules! global_dispatch_with_events {
|
macro_rules! global_dispatch_with_events {
|
||||||
($server:ty, $client:ty) => {
|
($server:ty, $client:ty) => {
|
||||||
impl<C: XConnection> GlobalDispatch<$server, Global> for ServerState<C>
|
impl<S: X11Selection> GlobalDispatch<$server, Global> for InnerServerState<S>
|
||||||
where
|
where
|
||||||
$server: Resource,
|
$server: Resource,
|
||||||
$client: Proxy,
|
$client: Proxy,
|
||||||
ServerState<C>: Dispatch<$server, Entity>,
|
InnerServerState<S>: Dispatch<$server, Entity>,
|
||||||
MyWorld: wayland_client::Dispatch<$client, Entity>,
|
MyWorld: wayland_client::Dispatch<$client, Entity>,
|
||||||
{
|
{
|
||||||
fn bind(
|
fn bind(
|
||||||
|
|
@ -1325,7 +1325,7 @@ global_dispatch_no_events!(
|
||||||
c_tablet::zwp_tablet_manager_v2::ZwpTabletManagerV2
|
c_tablet::zwp_tablet_manager_v2::ZwpTabletManagerV2
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<C: XConnection> GlobalDispatch<WlSeat, Global> for ServerState<C> {
|
impl<S: X11Selection> GlobalDispatch<WlSeat, Global> for InnerServerState<S> {
|
||||||
fn bind(
|
fn bind(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &DisplayHandle,
|
_: &DisplayHandle,
|
||||||
|
|
@ -1348,7 +1348,7 @@ impl<C: XConnection> GlobalDispatch<WlSeat, Global> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> GlobalDispatch<WlOutput, Global> for ServerState<C> {
|
impl<S: X11Selection> GlobalDispatch<WlOutput, Global> for InnerServerState<S> {
|
||||||
fn bind(
|
fn bind(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &DisplayHandle,
|
_: &DisplayHandle,
|
||||||
|
|
@ -1383,7 +1383,7 @@ impl<C: XConnection> GlobalDispatch<WlOutput, Global> for ServerState<C> {
|
||||||
}
|
}
|
||||||
global_dispatch_with_events!(WlDrmServer, WlDrmClient);
|
global_dispatch_with_events!(WlDrmServer, WlDrmClient);
|
||||||
|
|
||||||
impl<C: XConnection> GlobalDispatch<XwaylandShellV1, ()> for ServerState<C> {
|
impl<S: X11Selection> GlobalDispatch<XwaylandShellV1, ()> for InnerServerState<S> {
|
||||||
fn bind(
|
fn bind(
|
||||||
_: &mut Self,
|
_: &mut Self,
|
||||||
_: &DisplayHandle,
|
_: &DisplayHandle,
|
||||||
|
|
@ -1396,7 +1396,7 @@ impl<C: XConnection> GlobalDispatch<XwaylandShellV1, ()> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<XwaylandShellV1, ()> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<XwaylandShellV1, ()> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
client: &wayland_server::Client,
|
client: &wayland_server::Client,
|
||||||
|
|
@ -1432,7 +1432,7 @@ impl<C: XConnection> Dispatch<XwaylandShellV1, ()> for ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: XConnection> Dispatch<XwaylandSurfaceV1, Entity> for ServerState<C> {
|
impl<S: X11Selection> Dispatch<XwaylandSurfaceV1, Entity> for InnerServerState<S> {
|
||||||
fn request(
|
fn request(
|
||||||
state: &mut Self,
|
state: &mut Self,
|
||||||
_: &wayland_server::Client,
|
_: &wayland_server::Client,
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ impl Event for SurfaceEvents {
|
||||||
SurfaceEvents::Popup(event) => Self::popup_event(event, target, state),
|
SurfaceEvents::Popup(event) => Self::popup_event(event, target, state),
|
||||||
SurfaceEvents::FractionalScale(event) => match event {
|
SurfaceEvents::FractionalScale(event) => match event {
|
||||||
wp_fractional_scale_v1::Event::PreferredScale { scale } => {
|
wp_fractional_scale_v1::Event::PreferredScale { scale } => {
|
||||||
let entity = state.world.entity(target).unwrap();
|
let entity = state.inner.world.entity(target).unwrap();
|
||||||
let factor = scale as f64 / 120.0;
|
let factor = scale as f64 / 120.0;
|
||||||
debug!(
|
debug!(
|
||||||
"{} scale factor: {}",
|
"{} scale factor: {}",
|
||||||
|
|
@ -100,14 +100,14 @@ impl Event for SurfaceEvents {
|
||||||
|
|
||||||
if let Some(OnOutput(output)) = entity.get::<&OnOutput>().as_deref().copied() {
|
if let Some(OnOutput(output)) = entity.get::<&OnOutput>().as_deref().copied() {
|
||||||
if update_output_scale(
|
if update_output_scale(
|
||||||
state.world.query_one(output).unwrap(),
|
state.inner.world.query_one(output).unwrap(),
|
||||||
OutputScaleFactor::Fractional(factor),
|
OutputScaleFactor::Fractional(factor),
|
||||||
) {
|
) {
|
||||||
state.updated_outputs.push(output);
|
state.inner.updated_outputs.push(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if entity.has::<WindowData>() {
|
if entity.has::<WindowData>() {
|
||||||
update_surface_viewport(state.world.query_one(target).unwrap());
|
update_surface_viewport(state.inner.world.query_one(target).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
@ -123,6 +123,8 @@ impl SurfaceEvents {
|
||||||
state: &mut ServerState<impl XConnection>,
|
state: &mut ServerState<impl XConnection>,
|
||||||
) {
|
) {
|
||||||
use client::wl_surface::Event;
|
use client::wl_surface::Event;
|
||||||
|
let connection = &mut state.connection;
|
||||||
|
let state = &mut state.inner;
|
||||||
|
|
||||||
let data = state.world.entity(target).unwrap();
|
let data = state.world.entity(target).unwrap();
|
||||||
let surface = data.get::<&WlSurface>().unwrap();
|
let surface = data.get::<&WlSurface>().unwrap();
|
||||||
|
|
@ -151,11 +153,11 @@ impl SurfaceEvents {
|
||||||
x: dimensions.x - state.global_output_offset.x.value,
|
x: dimensions.x - state.global_output_offset.x.value,
|
||||||
y: dimensions.y - state.global_output_offset.y.value,
|
y: dimensions.y - state.global_output_offset.y.value,
|
||||||
},
|
},
|
||||||
&mut state.connection,
|
connection,
|
||||||
);
|
);
|
||||||
if state.last_focused_toplevel == Some(*window) {
|
if state.last_focused_toplevel == Some(*window) {
|
||||||
let output = get_output_name(Some(&on_output), &state.world);
|
let output = get_output_name(Some(&on_output), &state.world);
|
||||||
let conn = state.connection.as_mut().unwrap();
|
let conn = connection.as_mut().unwrap();
|
||||||
debug!("focused window changed outputs - resetting primary output");
|
debug!("focused window changed outputs - resetting primary output");
|
||||||
conn.focus_window(*window, output);
|
conn.focus_window(*window, output);
|
||||||
}
|
}
|
||||||
|
|
@ -204,6 +206,7 @@ impl SurfaceEvents {
|
||||||
state: &mut ServerState<C>,
|
state: &mut ServerState<C>,
|
||||||
) {
|
) {
|
||||||
let connection = state.connection.as_mut().unwrap();
|
let connection = state.connection.as_mut().unwrap();
|
||||||
|
let state = &mut state.inner;
|
||||||
let xdg_surface::Event::Configure { serial } = event else {
|
let xdg_surface::Event::Configure { serial } = event else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
@ -287,7 +290,7 @@ impl SurfaceEvents {
|
||||||
target: Entity,
|
target: Entity,
|
||||||
state: &mut ServerState<C>,
|
state: &mut ServerState<C>,
|
||||||
) {
|
) {
|
||||||
let data = state.world.entity(target).unwrap();
|
let data = state.inner.world.entity(target).unwrap();
|
||||||
match event {
|
match event {
|
||||||
xdg_toplevel::Event::Configure {
|
xdg_toplevel::Event::Configure {
|
||||||
width,
|
width,
|
||||||
|
|
@ -334,7 +337,7 @@ impl SurfaceEvents {
|
||||||
target: Entity,
|
target: Entity,
|
||||||
state: &mut ServerState<C>,
|
state: &mut ServerState<C>,
|
||||||
) {
|
) {
|
||||||
let data = state.world.entity(target).unwrap();
|
let data = state.inner.world.entity(target).unwrap();
|
||||||
match event {
|
match event {
|
||||||
xdg_popup::Event::Configure {
|
xdg_popup::Event::Configure {
|
||||||
x,
|
x,
|
||||||
|
|
@ -416,13 +419,18 @@ pub(super) fn update_surface_viewport(
|
||||||
impl Event for client::wl_buffer::Event {
|
impl Event for client::wl_buffer::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
// The only event from a buffer would be the release.
|
// The only event from a buffer would be the release.
|
||||||
state.world.get::<&WlBuffer>(target).unwrap().release();
|
state
|
||||||
|
.inner
|
||||||
|
.world
|
||||||
|
.get::<&WlBuffer>(target)
|
||||||
|
.unwrap()
|
||||||
|
.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event for client::wl_seat::Event {
|
impl Event for client::wl_seat::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let server = state.world.get::<&WlSeat>(target).unwrap();
|
let server = state.inner.world.get::<&WlSeat>(target).unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
server, self => [
|
server, self => [
|
||||||
Capabilities { |capabilities| convert_wenum(capabilities) },
|
Capabilities { |capabilities| convert_wenum(capabilities) },
|
||||||
|
|
@ -453,10 +461,11 @@ impl Event for client::wl_pointer::Event {
|
||||||
surface_y,
|
surface_y,
|
||||||
} => {
|
} => {
|
||||||
let mut cmd = CommandBuffer::new();
|
let mut cmd = CommandBuffer::new();
|
||||||
let pending_enter = state.world.remove_one::<PendingEnter>(target).ok();
|
let pending_enter = state.inner.world.remove_one::<PendingEnter>(target).ok();
|
||||||
let server = state.world.get::<&WlPointer>(target).unwrap();
|
let server = state.inner.world.get::<&WlPointer>(target).unwrap();
|
||||||
let mut query = surface.data().copied().and_then(|e| {
|
let mut query = surface.data().copied().and_then(|e| {
|
||||||
state
|
state
|
||||||
|
.inner
|
||||||
.world
|
.world
|
||||||
.query_one::<(&WlSurface, &SurfaceRole, &SurfaceScaleFactor, &x::Window)>(e)
|
.query_one::<(&WlSurface, &SurfaceRole, &SurfaceScaleFactor, &x::Window)>(e)
|
||||||
.ok()
|
.ok()
|
||||||
|
|
@ -475,7 +484,7 @@ impl Event for client::wl_pointer::Event {
|
||||||
server.enter(serial, surface, surface_x * scale.0, surface_y * scale.0);
|
server.enter(serial, surface, surface_x * scale.0, surface_y * scale.0);
|
||||||
state.connection.as_mut().unwrap().raise_to_top(*window);
|
state.connection.as_mut().unwrap().raise_to_top(*window);
|
||||||
if !surface_is_popup {
|
if !surface_is_popup {
|
||||||
state.last_hovered = Some(*window);
|
state.inner.last_hovered = Some(*window);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -504,21 +513,22 @@ impl Event for client::wl_pointer::Event {
|
||||||
}
|
}
|
||||||
drop(query);
|
drop(query);
|
||||||
drop(server);
|
drop(server);
|
||||||
cmd.run_on(&mut state.world);
|
cmd.run_on(&mut state.inner.world);
|
||||||
}
|
}
|
||||||
client::wl_pointer::Event::Leave { serial, surface } => {
|
client::wl_pointer::Event::Leave { serial, surface } => {
|
||||||
let _ = state.world.remove_one::<PendingEnter>(target);
|
let _ = state.inner.world.remove_one::<PendingEnter>(target);
|
||||||
if !surface.is_alive() {
|
if !surface.is_alive() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug!("leaving surface ({serial})");
|
debug!("leaving surface ({serial})");
|
||||||
let _ = state.world.remove_one::<PendingEnter>(target);
|
let _ = state.inner.world.remove_one::<PendingEnter>(target);
|
||||||
if let Some(surface) = surface
|
if let Some(surface) = surface
|
||||||
.data()
|
.data()
|
||||||
.copied()
|
.copied()
|
||||||
.and_then(|key| state.world.get::<&WlSurface>(key).ok())
|
.and_then(|key| state.inner.world.get::<&WlSurface>(key).ok())
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
|
.inner
|
||||||
.world
|
.world
|
||||||
.get::<&WlPointer>(target)
|
.get::<&WlPointer>(target)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -532,7 +542,7 @@ impl Event for client::wl_pointer::Event {
|
||||||
surface_x,
|
surface_x,
|
||||||
surface_y,
|
surface_y,
|
||||||
} => {
|
} => {
|
||||||
let pending_enter = state.world.get::<&PendingEnter>(target).ok();
|
let pending_enter = state.inner.world.get::<&PendingEnter>(target).ok();
|
||||||
match pending_enter.as_deref() {
|
match pending_enter.as_deref() {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
let PendingEnter(client::wl_pointer::Event::Enter {
|
let PendingEnter(client::wl_pointer::Event::Enter {
|
||||||
|
|
@ -547,7 +557,7 @@ impl Event for client::wl_pointer::Event {
|
||||||
if surface
|
if surface
|
||||||
.data()
|
.data()
|
||||||
.copied()
|
.copied()
|
||||||
.is_some_and(|key| state.world.contains(key))
|
.is_some_and(|key| state.inner.world.contains(key))
|
||||||
{
|
{
|
||||||
trace!("resending enter ({serial}) before motion");
|
trace!("resending enter ({serial}) before motion");
|
||||||
let enter_event = client::wl_pointer::Event::Enter {
|
let enter_event = client::wl_pointer::Event::Enter {
|
||||||
|
|
@ -567,6 +577,7 @@ impl Event for client::wl_pointer::Event {
|
||||||
None => {
|
None => {
|
||||||
drop(pending_enter);
|
drop(pending_enter);
|
||||||
let (server, scale) = state
|
let (server, scale) = state
|
||||||
|
.inner
|
||||||
.world
|
.world
|
||||||
.query_one_mut::<(&WlPointer, &SurfaceScaleFactor)>(target)
|
.query_one_mut::<(&WlPointer, &SurfaceScaleFactor)>(target)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -581,7 +592,7 @@ impl Event for client::wl_pointer::Event {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let server = state.world.get::<&WlPointer>(target).unwrap();
|
let server = state.inner.world.get::<&WlPointer>(target).unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
server, self => [
|
server, self => [
|
||||||
Frame,
|
Frame,
|
||||||
|
|
@ -624,6 +635,7 @@ impl Event for client::wl_pointer::Event {
|
||||||
|
|
||||||
impl Event for client::wl_keyboard::Event {
|
impl Event for client::wl_keyboard::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
let data = state.world.entity(target).unwrap();
|
let data = state.world.entity(target).unwrap();
|
||||||
let keyboard = data.get::<&WlKeyboard>().unwrap();
|
let keyboard = data.get::<&WlKeyboard>().unwrap();
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -714,6 +726,7 @@ impl Event for client::wl_keyboard::Event {
|
||||||
|
|
||||||
impl Event for client::wl_touch::Event {
|
impl Event for client::wl_touch::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
match self {
|
match self {
|
||||||
Self::Down {
|
Self::Down {
|
||||||
serial,
|
serial,
|
||||||
|
|
@ -855,6 +868,8 @@ fn update_output_offset(
|
||||||
y: i32,
|
y: i32,
|
||||||
state: &mut ServerState<impl XConnection>,
|
state: &mut ServerState<impl XConnection>,
|
||||||
) {
|
) {
|
||||||
|
let connection = &mut state.connection;
|
||||||
|
let state = &mut state.inner;
|
||||||
{
|
{
|
||||||
let mut dimensions = state.world.get::<&mut OutputDimensions>(output).unwrap();
|
let mut dimensions = state.world.get::<&mut OutputDimensions>(output).unwrap();
|
||||||
if matches!(source, OutputDimensionsSource::Wl { .. })
|
if matches!(source, OutputDimensionsSource::Wl { .. })
|
||||||
|
|
@ -893,7 +908,7 @@ fn update_output_offset(
|
||||||
output,
|
output,
|
||||||
&state.global_output_offset,
|
&state.global_output_offset,
|
||||||
&state.world,
|
&state.world,
|
||||||
&mut state.connection,
|
connection,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1027,6 +1042,7 @@ impl OutputEvent {
|
||||||
y,
|
y,
|
||||||
state,
|
state,
|
||||||
);
|
);
|
||||||
|
let state = state.inner_mut();
|
||||||
|
|
||||||
let (output, dimensions, xdg) = state
|
let (output, dimensions, xdg) = state
|
||||||
.world
|
.world
|
||||||
|
|
@ -1068,6 +1084,7 @@ impl OutputEvent {
|
||||||
height,
|
height,
|
||||||
refresh,
|
refresh,
|
||||||
} => {
|
} => {
|
||||||
|
let state = state.inner_mut();
|
||||||
let (output, dimensions) = state
|
let (output, dimensions) = state
|
||||||
.world
|
.world
|
||||||
.query_one_mut::<(&WlOutput, &mut OutputDimensions)>(target)
|
.query_one_mut::<(&WlOutput, &mut OutputDimensions)>(target)
|
||||||
|
|
@ -1084,6 +1101,7 @@ impl OutputEvent {
|
||||||
output.mode(convert_wenum(flags), width, height, refresh);
|
output.mode(convert_wenum(flags), width, height, refresh);
|
||||||
}
|
}
|
||||||
Event::Scale { factor } => {
|
Event::Scale { factor } => {
|
||||||
|
let state = state.inner_mut();
|
||||||
debug!(
|
debug!(
|
||||||
"{} scale: {factor}",
|
"{} scale: {factor}",
|
||||||
state.world.get::<&WlOutput>(target).unwrap().id()
|
state.world.get::<&WlOutput>(target).unwrap().id()
|
||||||
|
|
@ -1099,6 +1117,7 @@ impl OutputEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Name { name } => {
|
Event::Name { name } => {
|
||||||
|
let state = state.inner_mut();
|
||||||
state
|
state
|
||||||
.world
|
.world
|
||||||
.get::<&WlOutput>(target)
|
.get::<&WlOutput>(target)
|
||||||
|
|
@ -1107,7 +1126,7 @@ impl OutputEvent {
|
||||||
state.world.insert(target, (OutputName(name),)).unwrap();
|
state.world.insert(target, (OutputName(name),)).unwrap();
|
||||||
}
|
}
|
||||||
_ => simple_event_shunt! {
|
_ => simple_event_shunt! {
|
||||||
state.world.get::<&WlOutput>(target).unwrap(),
|
state.inner.world.get::<&WlOutput>(target).unwrap(),
|
||||||
event: client::wl_output::Event => [
|
event: client::wl_output::Event => [
|
||||||
Description { description },
|
Description { description },
|
||||||
Done
|
Done
|
||||||
|
|
@ -1126,6 +1145,7 @@ impl OutputEvent {
|
||||||
match event {
|
match event {
|
||||||
Event::LogicalPosition { x, y } => {
|
Event::LogicalPosition { x, y } => {
|
||||||
update_output_offset(target, OutputDimensionsSource::Xdg, x, y, state);
|
update_output_offset(target, OutputDimensionsSource::Xdg, x, y, state);
|
||||||
|
let state = state.inner_mut();
|
||||||
state
|
state
|
||||||
.world
|
.world
|
||||||
.get::<&XdgOutputServer>(target)
|
.get::<&XdgOutputServer>(target)
|
||||||
|
|
@ -1136,6 +1156,7 @@ impl OutputEvent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Event::LogicalSize { .. } => {
|
Event::LogicalSize { .. } => {
|
||||||
|
let state = state.inner_mut();
|
||||||
let (xdg, dimensions) = state
|
let (xdg, dimensions) = state
|
||||||
.world
|
.world
|
||||||
.query_one_mut::<(&XdgOutputServer, &OutputDimensions)>(target)
|
.query_one_mut::<(&XdgOutputServer, &OutputDimensions)>(target)
|
||||||
|
|
@ -1147,7 +1168,7 @@ impl OutputEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => simple_event_shunt! {
|
_ => simple_event_shunt! {
|
||||||
state.world.get::<&XdgOutputServer>(target).unwrap(),
|
state.inner.world.get::<&XdgOutputServer>(target).unwrap(),
|
||||||
event: zxdg_output_v1::Event => [
|
event: zxdg_output_v1::Event => [
|
||||||
Done,
|
Done,
|
||||||
Name { name },
|
Name { name },
|
||||||
|
|
@ -1160,7 +1181,7 @@ impl OutputEvent {
|
||||||
|
|
||||||
impl Event for wl_drm::client::wl_drm::Event {
|
impl Event for wl_drm::client::wl_drm::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let server = state.world.get::<&WlDrmServer>(target).unwrap();
|
let server = state.inner.world.get::<&WlDrmServer>(target).unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
server, self => [
|
server, self => [
|
||||||
Device { name },
|
Device { name },
|
||||||
|
|
@ -1175,6 +1196,7 @@ impl Event for wl_drm::client::wl_drm::Event {
|
||||||
impl Event for c_dmabuf::zwp_linux_dmabuf_feedback_v1::Event {
|
impl Event for c_dmabuf::zwp_linux_dmabuf_feedback_v1::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let server = state
|
let server = state
|
||||||
|
.inner
|
||||||
.world
|
.world
|
||||||
.get::<&s_dmabuf::zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1>(target)
|
.get::<&s_dmabuf::zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1>(target)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1194,7 +1216,11 @@ impl Event for c_dmabuf::zwp_linux_dmabuf_feedback_v1::Event {
|
||||||
|
|
||||||
impl Event for zwp_relative_pointer_v1::Event {
|
impl Event for zwp_relative_pointer_v1::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let server = state.world.get::<&RelativePointerServer>(target).unwrap();
|
let server = state
|
||||||
|
.inner
|
||||||
|
.world
|
||||||
|
.get::<&RelativePointerServer>(target)
|
||||||
|
.unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
server, self => [
|
server, self => [
|
||||||
RelativeMotion {
|
RelativeMotion {
|
||||||
|
|
@ -1212,7 +1238,11 @@ impl Event for zwp_relative_pointer_v1::Event {
|
||||||
|
|
||||||
impl Event for zwp_locked_pointer_v1::Event {
|
impl Event for zwp_locked_pointer_v1::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let server = state.world.get::<&LockedPointerServer>(target).unwrap();
|
let server = state
|
||||||
|
.inner
|
||||||
|
.world
|
||||||
|
.get::<&LockedPointerServer>(target)
|
||||||
|
.unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
server, self => [
|
server, self => [
|
||||||
Locked,
|
Locked,
|
||||||
|
|
@ -1224,7 +1254,11 @@ impl Event for zwp_locked_pointer_v1::Event {
|
||||||
|
|
||||||
impl Event for zwp_confined_pointer_v1::Event {
|
impl Event for zwp_confined_pointer_v1::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let server = state.world.get::<&ConfinedPointerServer>(target).unwrap();
|
let server = state
|
||||||
|
.inner
|
||||||
|
.world
|
||||||
|
.get::<&ConfinedPointerServer>(target)
|
||||||
|
.unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
server, self => [
|
server, self => [
|
||||||
Confined,
|
Confined,
|
||||||
|
|
@ -1236,6 +1270,7 @@ impl Event for zwp_confined_pointer_v1::Event {
|
||||||
|
|
||||||
impl Event for zwp_tablet_seat_v2::Event {
|
impl Event for zwp_tablet_seat_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
let seat = state.world.get::<&TabletSeatServer>(target).unwrap();
|
let seat = state.world.get::<&TabletSeatServer>(target).unwrap();
|
||||||
match self {
|
match self {
|
||||||
Self::TabletAdded { id } => {
|
Self::TabletAdded { id } => {
|
||||||
|
|
@ -1263,7 +1298,7 @@ impl Event for zwp_tablet_seat_v2::Event {
|
||||||
|
|
||||||
impl Event for zwp_tablet_v2::Event {
|
impl Event for zwp_tablet_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
let tab = state.world.get::<&TabletServer>(target).unwrap();
|
let tab = state.inner.world.get::<&TabletServer>(target).unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
tab, self => [
|
tab, self => [
|
||||||
Name { name },
|
Name { name },
|
||||||
|
|
@ -1278,6 +1313,7 @@ impl Event for zwp_tablet_v2::Event {
|
||||||
|
|
||||||
impl Event for zwp_tablet_pad_v2::Event {
|
impl Event for zwp_tablet_pad_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
let pad = state.world.get::<&TabletPadServer>(target).unwrap();
|
let pad = state.world.get::<&TabletPadServer>(target).unwrap();
|
||||||
let s_surf;
|
let s_surf;
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -1331,6 +1367,7 @@ impl Event for zwp_tablet_pad_v2::Event {
|
||||||
|
|
||||||
impl Event for zwp_tablet_tool_v2::Event {
|
impl Event for zwp_tablet_tool_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
match self {
|
match self {
|
||||||
Self::ProximityIn {
|
Self::ProximityIn {
|
||||||
serial,
|
serial,
|
||||||
|
|
@ -1407,20 +1444,24 @@ impl Event for zwp_tablet_tool_v2::Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn from_client<Server: Resource + 'static, Client: Proxy + Send + Sync + 'static, C: XConnection>(
|
fn from_client<
|
||||||
|
Server: Resource + 'static,
|
||||||
|
Client: Proxy + Send + Sync + 'static,
|
||||||
|
S: X11Selection + 'static,
|
||||||
|
>(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
state: &ServerState<C>,
|
state: &InnerServerState<S>,
|
||||||
) -> (Entity, Server)
|
) -> (Entity, Server)
|
||||||
where
|
where
|
||||||
Client::Event: Send + Into<ObjectEvent>,
|
Client::Event: Send + Into<ObjectEvent>,
|
||||||
ServerState<C>: wayland_server::Dispatch<Server, Entity>,
|
InnerServerState<S>: wayland_server::Dispatch<Server, Entity>,
|
||||||
{
|
{
|
||||||
let entity = state.world.reserve_entity();
|
let entity = state.world.reserve_entity();
|
||||||
let server = state
|
let server = state
|
||||||
.client
|
.client
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.create_resource::<_, _, ServerState<C>>(&state.dh, 1, entity)
|
.create_resource::<_, _, InnerServerState<S>>(&state.dh, 1, entity)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let obj_key: &LateInitObjectKey<Client> = client.data().unwrap();
|
let obj_key: &LateInitObjectKey<Client> = client.data().unwrap();
|
||||||
obj_key.init(entity);
|
obj_key.init(entity);
|
||||||
|
|
@ -1429,6 +1470,7 @@ where
|
||||||
|
|
||||||
impl Event for zwp_tablet_pad_group_v2::Event {
|
impl Event for zwp_tablet_pad_group_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
let group = state.world.get::<&TabletPadGroupServer>(target).unwrap();
|
let group = state.world.get::<&TabletPadGroupServer>(target).unwrap();
|
||||||
match self {
|
match self {
|
||||||
Self::Buttons { buttons } => group.buttons(buttons),
|
Self::Buttons { buttons } => group.buttons(buttons),
|
||||||
|
|
@ -1457,6 +1499,7 @@ impl Event for zwp_tablet_pad_group_v2::Event {
|
||||||
|
|
||||||
impl Event for zwp_tablet_pad_ring_v2::Event {
|
impl Event for zwp_tablet_pad_ring_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
let ring = state.world.get::<&TabletPadRingServer>(target).unwrap();
|
let ring = state.world.get::<&TabletPadRingServer>(target).unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
ring, self => [
|
ring, self => [
|
||||||
|
|
@ -1471,6 +1514,7 @@ impl Event for zwp_tablet_pad_ring_v2::Event {
|
||||||
|
|
||||||
impl Event for zwp_tablet_pad_strip_v2::Event {
|
impl Event for zwp_tablet_pad_strip_v2::Event {
|
||||||
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
fn handle<C: XConnection>(self, target: Entity, state: &mut ServerState<C>) {
|
||||||
|
let state = state.inner_mut();
|
||||||
let strip = state.world.get::<&TabletPadStripServer>(target).unwrap();
|
let strip = state.world.get::<&TabletPadStripServer>(target).unwrap();
|
||||||
simple_event_shunt! {
|
simple_event_shunt! {
|
||||||
strip, self => [
|
strip, self => [
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,7 @@ enum ObjectEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_globals<'a, C: XConnection>(
|
fn handle_globals<'a, S: X11Selection + 'static>(
|
||||||
dh: &DisplayHandle,
|
dh: &DisplayHandle,
|
||||||
globals: impl IntoIterator<Item = &'a Global>,
|
globals: impl IntoIterator<Item = &'a Global>,
|
||||||
) {
|
) {
|
||||||
|
|
@ -353,7 +353,7 @@ fn handle_globals<'a, C: XConnection>(
|
||||||
$(
|
$(
|
||||||
ref x if x == <$global>::interface().name => {
|
ref x if x == <$global>::interface().name => {
|
||||||
let version = u32::min(global.version, <$global>::interface().version);
|
let version = u32::min(global.version, <$global>::interface().version);
|
||||||
dh.create_global::<ServerState<C>, $global, Global>(version, global.clone());
|
dh.create_global::<InnerServerState<S>, $global, Global>(version, global.clone());
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -394,6 +394,11 @@ struct GlobalOutputOffset {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ServerState<C: XConnection> {
|
pub struct ServerState<C: XConnection> {
|
||||||
|
inner: InnerServerState<C::X11Selection>,
|
||||||
|
pub connection: Option<C>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InnerServerState<S: X11Selection> {
|
||||||
dh: DisplayHandle,
|
dh: DisplayHandle,
|
||||||
windows: HashMap<x::Window, Entity>,
|
windows: HashMap<x::Window, Entity>,
|
||||||
pids: HashSet<u32>,
|
pids: HashSet<u32>,
|
||||||
|
|
@ -406,13 +411,12 @@ pub struct ServerState<C: XConnection> {
|
||||||
unfocus: bool,
|
unfocus: bool,
|
||||||
last_focused_toplevel: Option<x::Window>,
|
last_focused_toplevel: Option<x::Window>,
|
||||||
last_hovered: Option<x::Window>,
|
last_hovered: Option<x::Window>,
|
||||||
pub connection: Option<C>,
|
|
||||||
|
|
||||||
xdg_wm_base: XdgWmBase,
|
xdg_wm_base: XdgWmBase,
|
||||||
viewporter: WpViewporter,
|
viewporter: WpViewporter,
|
||||||
fractional_scale: Option<WpFractionalScaleManagerV1>,
|
fractional_scale: Option<WpFractionalScaleManagerV1>,
|
||||||
decoration_manager: Option<ZxdgDecorationManagerV1>,
|
decoration_manager: Option<ZxdgDecorationManagerV1>,
|
||||||
clipboard_data: Option<ClipboardData<C::X11Selection>>,
|
clipboard_data: Option<ClipboardData<S>>,
|
||||||
last_kb_serial: Option<(client::wl_seat::WlSeat, u32)>,
|
last_kb_serial: Option<(client::wl_seat::WlSeat, u32)>,
|
||||||
activation_state: Option<ActivationState>,
|
activation_state: Option<ActivationState>,
|
||||||
global_output_offset: GlobalOutputOffset,
|
global_output_offset: GlobalOutputOffset,
|
||||||
|
|
@ -472,12 +476,12 @@ impl<C: XConnection> ServerState<C> {
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
dh.create_global::<Self, XwaylandShellV1, _>(1, ());
|
dh.create_global::<InnerServerState<C::X11Selection>, XwaylandShellV1, _>(1, ());
|
||||||
global_list
|
global_list
|
||||||
.contents()
|
.contents()
|
||||||
.with_list(|globals| handle_globals::<C>(&dh, globals));
|
.with_list(|globals| handle_globals::<C::X11Selection>(&dh, globals));
|
||||||
|
|
||||||
Self {
|
let inner = InnerServerState {
|
||||||
windows: HashMap::new(),
|
windows: HashMap::new(),
|
||||||
pids: HashSet::new(),
|
pids: HashSet::new(),
|
||||||
client: None,
|
client: None,
|
||||||
|
|
@ -488,7 +492,6 @@ impl<C: XConnection> ServerState<C> {
|
||||||
unfocus: false,
|
unfocus: false,
|
||||||
last_focused_toplevel: None,
|
last_focused_toplevel: None,
|
||||||
last_hovered: None,
|
last_hovered: None,
|
||||||
connection: None,
|
|
||||||
xdg_wm_base,
|
xdg_wm_base,
|
||||||
viewporter,
|
viewporter,
|
||||||
fractional_scale,
|
fractional_scale,
|
||||||
|
|
@ -510,14 +513,276 @@ impl<C: XConnection> ServerState<C> {
|
||||||
new_scale: None,
|
new_scale: None,
|
||||||
decoration_manager,
|
decoration_manager,
|
||||||
world: MyWorld::new(global_list),
|
world: MyWorld::new(global_list),
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
inner,
|
||||||
|
connection: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C: XConnection> ServerState<C> {
|
||||||
|
pub fn inner_mut(&mut self) -> &mut InnerServerState<C::X11Selection> {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clientside_fd(&self) -> BorrowedFd<'_> {
|
pub fn clientside_fd(&self) -> BorrowedFd<'_> {
|
||||||
self.queue.as_fd()
|
self.inner.clientside_fd()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect(&mut self, connection: UnixStream) {
|
pub fn connect(&mut self, connection: UnixStream) {
|
||||||
|
self.inner.connect(connection)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_new_globals(&mut self) {
|
||||||
|
self.inner.handle_new_globals()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_x_connection(&mut self, connection: C) {
|
||||||
|
self.connection = Some(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_window(
|
||||||
|
&mut self,
|
||||||
|
window: x::Window,
|
||||||
|
override_redirect: bool,
|
||||||
|
dims: WindowDims,
|
||||||
|
pid: Option<u32>,
|
||||||
|
) {
|
||||||
|
self.inner.new_window(window, override_redirect, dims, pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_popup(&mut self, window: x::Window, is_popup: bool) {
|
||||||
|
self.inner.set_popup(window, is_popup)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_win_title(&mut self, window: x::Window, name: WmName) {
|
||||||
|
self.inner.set_win_title(window, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_win_class(&mut self, window: x::Window, class: String) {
|
||||||
|
self.inner.set_win_class(window, class)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_win_hints(&mut self, window: x::Window, hints: WmHints) {
|
||||||
|
self.inner.set_win_hints(window, hints)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_size_hints(&mut self, window: x::Window, hints: WmNormalHints) {
|
||||||
|
self.inner.set_size_hints(window, hints)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_win_decorations(&mut self, window: x::Window, decorations: Decorations) {
|
||||||
|
self.inner.set_win_decorations(window, decorations)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_window_serial(&mut self, window: x::Window, serial: [u32; 2]) {
|
||||||
|
self.inner.set_window_serial(window, serial)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn can_change_position(&self, window: x::Window) -> bool {
|
||||||
|
self.inner.can_change_position(window)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reconfigure_window(&mut self, event: x::ConfigureNotifyEvent) {
|
||||||
|
self.inner.reconfigure_window(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_window(&mut self, window: x::Window) {
|
||||||
|
self.inner.map_window(window)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unmap_window(&mut self, window: x::Window) {
|
||||||
|
self.inner.unmap_window(window)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_fullscreen(&mut self, window: x::Window, state: super::xstate::SetState) {
|
||||||
|
self.inner.set_fullscreen(window, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_transient_for(&mut self, window: x::Window, parent: x::Window) {
|
||||||
|
self.inner.set_transient_for(window, parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn activate_window(&mut self, window: x::Window) {
|
||||||
|
self.inner.activate_window(window)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy_window(&mut self, window: x::Window) {
|
||||||
|
self.inner.destroy_window(window)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_copy_paste_source(&mut self, selection: &Rc<C::X11Selection>) {
|
||||||
|
self.inner.set_copy_paste_source(selection)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self) {
|
||||||
|
if let Some(r) = self.inner.queue.prepare_read() {
|
||||||
|
let fd = r.connection_fd();
|
||||||
|
let pollfd = PollFd::new(&fd, PollFlags::IN);
|
||||||
|
if poll(&mut [pollfd], 0).unwrap() > 0 {
|
||||||
|
let _ = r.read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.inner
|
||||||
|
.queue
|
||||||
|
.dispatch_pending(&mut self.inner.world)
|
||||||
|
.expect("Failed dispatching client side Wayland events");
|
||||||
|
self.handle_clientside_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_clientside_events(&mut self) {
|
||||||
|
self.handle_new_globals();
|
||||||
|
|
||||||
|
for (target, event) in self.inner.world.read_events() {
|
||||||
|
if !self.inner.world.contains(target) {
|
||||||
|
warn!("could not handle clientside event: stale object");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
event.handle(target, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.inner.global_offset_updated {
|
||||||
|
if self.inner.global_output_offset.x.owner.is_none()
|
||||||
|
|| self.inner.global_output_offset.y.owner.is_none()
|
||||||
|
{
|
||||||
|
self.calc_global_output_offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"updated global output offset: {}x{}",
|
||||||
|
self.inner.global_output_offset.x.value, self.inner.global_output_offset.y.value
|
||||||
|
);
|
||||||
|
for (e, _) in self.inner.world.query::<&WlOutput>().iter() {
|
||||||
|
event::update_global_output_offset(
|
||||||
|
e,
|
||||||
|
&self.inner.global_output_offset,
|
||||||
|
&self.inner.world,
|
||||||
|
&mut self.connection,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self.inner.global_offset_updated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.inner.updated_outputs.is_empty() {
|
||||||
|
for output in self.inner.updated_outputs.drain(..) {
|
||||||
|
let output_scale = self.inner.world.get::<&OutputScaleFactor>(output).unwrap();
|
||||||
|
if matches!(*output_scale, OutputScaleFactor::Output(..)) {
|
||||||
|
let mut surface_query = self
|
||||||
|
.inner
|
||||||
|
.world
|
||||||
|
.query::<(&OnOutput, &mut SurfaceScaleFactor)>()
|
||||||
|
.with::<(&WindowData, &WlSurface)>();
|
||||||
|
|
||||||
|
let mut surfaces = vec![];
|
||||||
|
for (surface, (OnOutput(s_output), surface_scale)) in surface_query.iter() {
|
||||||
|
if *s_output == output {
|
||||||
|
surface_scale.0 = output_scale.get();
|
||||||
|
surfaces.push(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(surface_query);
|
||||||
|
for surface in surfaces {
|
||||||
|
update_surface_viewport(self.inner.world.query_one(surface).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut mixed_scale = false;
|
||||||
|
let mut scale;
|
||||||
|
|
||||||
|
let mut outputs = self
|
||||||
|
.inner
|
||||||
|
.world
|
||||||
|
.query_mut::<&OutputScaleFactor>()
|
||||||
|
.into_iter();
|
||||||
|
let (_, output_scale) = outputs.next().unwrap();
|
||||||
|
|
||||||
|
scale = output_scale.get();
|
||||||
|
|
||||||
|
for (_, output_scale) in outputs {
|
||||||
|
if output_scale.get() != scale {
|
||||||
|
mixed_scale = true;
|
||||||
|
scale = scale.min(output_scale.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mixed_scale {
|
||||||
|
warn!("Mixed output scales detected, choosing to give apps the smallest detected scale ({scale}x)");
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("Using new scale {scale}");
|
||||||
|
self.inner.new_scale = Some(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if let Some(FocusData {
|
||||||
|
window,
|
||||||
|
output_name,
|
||||||
|
}) = self.inner.to_focus.take()
|
||||||
|
{
|
||||||
|
let conn = self.connection.as_mut().unwrap();
|
||||||
|
debug!("focusing window {window:?}");
|
||||||
|
conn.focus_window(window, output_name);
|
||||||
|
self.inner.last_focused_toplevel = Some(window);
|
||||||
|
} else if self.inner.unfocus {
|
||||||
|
let conn = self.connection.as_mut().unwrap();
|
||||||
|
conn.focus_window(x::WINDOW_NONE, None);
|
||||||
|
}
|
||||||
|
self.inner.unfocus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.handle_clipboard_events();
|
||||||
|
self.handle_activations();
|
||||||
|
self.inner
|
||||||
|
.queue
|
||||||
|
.flush()
|
||||||
|
.expect("Failed flushing clientside events");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_global_scale(&mut self) -> Option<f64> {
|
||||||
|
self.inner.new_global_scale()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_selection(&mut self) -> Option<ForeignSelection> {
|
||||||
|
self.inner.new_selection()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_clipboard_events(&mut self) {
|
||||||
|
self.inner.handle_clipboard_events()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_activations(&mut self) {
|
||||||
|
self.inner.handle_activations()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_global_output_offset(&mut self) {
|
||||||
|
self.inner.calc_global_output_offset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// create_role_window is only called in a Dispatch impl, a trait impl necessarily moved to be
|
||||||
|
// on the ineer value. create_toplevel and create_popup are only called by that create_role_window
|
||||||
|
// call, so none of them need wrapper functions.
|
||||||
|
|
||||||
|
fn close_x_window(&mut self, window: x::Window) {
|
||||||
|
debug!("sending close request to {window:?}");
|
||||||
|
self.connection.as_mut().unwrap().close_window(window);
|
||||||
|
if self.inner.last_focused_toplevel == Some(window) {
|
||||||
|
self.inner.last_focused_toplevel.take();
|
||||||
|
}
|
||||||
|
if self.inner.last_hovered == Some(window) {
|
||||||
|
self.inner.last_hovered.take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: X11Selection + 'static> InnerServerState<S> {
|
||||||
|
fn clientside_fd(&self) -> BorrowedFd<'_> {
|
||||||
|
self.queue.as_fd()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect(&mut self, connection: UnixStream) {
|
||||||
self.client = Some(
|
self.client = Some(
|
||||||
self.dh
|
self.dh
|
||||||
.insert_client(connection, std::sync::Arc::new(()))
|
.insert_client(connection, std::sync::Arc::new(()))
|
||||||
|
|
@ -525,16 +790,12 @@ impl<C: XConnection> ServerState<C> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_x_connection(&mut self, connection: C) {
|
|
||||||
self.connection = Some(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_new_globals(&mut self) {
|
fn handle_new_globals(&mut self) {
|
||||||
let globals = std::mem::take(&mut self.world.new_globals);
|
let globals = std::mem::take(&mut self.world.new_globals);
|
||||||
handle_globals::<C>(&self.dh, globals.iter());
|
handle_globals::<S>(&self.dh, globals.iter());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_window(
|
fn new_window(
|
||||||
&mut self,
|
&mut self,
|
||||||
window: x::Window,
|
window: x::Window,
|
||||||
override_redirect: bool,
|
override_redirect: bool,
|
||||||
|
|
@ -559,7 +820,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
self.windows.insert(window, id);
|
self.windows.insert(window, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_popup(&mut self, window: x::Window, is_popup: bool) {
|
fn set_popup(&mut self, window: x::Window, is_popup: bool) {
|
||||||
let Some(id) = self.windows.get(&window).copied() else {
|
let Some(id) = self.windows.get(&window).copied() else {
|
||||||
debug!("not setting popup for unknown window {window:?}");
|
debug!("not setting popup for unknown window {window:?}");
|
||||||
return;
|
return;
|
||||||
|
|
@ -572,7 +833,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
.is_popup = is_popup;
|
.is_popup = is_popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_win_title(&mut self, window: x::Window, name: WmName) {
|
fn set_win_title(&mut self, window: x::Window, name: WmName) {
|
||||||
let Some(data) = self
|
let Some(data) = self
|
||||||
.windows
|
.windows
|
||||||
.get(&window)
|
.get(&window)
|
||||||
|
|
@ -610,7 +871,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_win_class(&mut self, window: x::Window, class: String) {
|
fn set_win_class(&mut self, window: x::Window, class: String) {
|
||||||
let Some(data) = self
|
let Some(data) = self
|
||||||
.windows
|
.windows
|
||||||
.get(&window)
|
.get(&window)
|
||||||
|
|
@ -631,7 +892,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_win_hints(&mut self, window: x::Window, hints: WmHints) {
|
fn set_win_hints(&mut self, window: x::Window, hints: WmHints) {
|
||||||
let Some(id) = self.windows.get(&window).copied() else {
|
let Some(id) = self.windows.get(&window).copied() else {
|
||||||
debug!("not setting hints for unknown window {window:?}");
|
debug!("not setting hints for unknown window {window:?}");
|
||||||
return;
|
return;
|
||||||
|
|
@ -640,7 +901,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
self.world.get::<&mut WindowData>(id).unwrap().attrs.group = hints.window_group;
|
self.world.get::<&mut WindowData>(id).unwrap().attrs.group = hints.window_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_size_hints(&mut self, window: x::Window, hints: WmNormalHints) {
|
fn set_size_hints(&mut self, window: x::Window, hints: WmNormalHints) {
|
||||||
let Some(data) = self
|
let Some(data) = self
|
||||||
.windows
|
.windows
|
||||||
.get(&window)
|
.get(&window)
|
||||||
|
|
@ -674,7 +935,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_win_decorations(&mut self, window: x::Window, decorations: Decorations) {
|
fn set_win_decorations(&mut self, window: x::Window, decorations: Decorations) {
|
||||||
if self.decoration_manager.is_none() {
|
if self.decoration_manager.is_none() {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -705,7 +966,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_window_serial(&mut self, window: x::Window, serial: [u32; 2]) {
|
fn set_window_serial(&mut self, window: x::Window, serial: [u32; 2]) {
|
||||||
let Some(id) = self.windows.get(&window).copied() else {
|
let Some(id) = self.windows.get(&window).copied() else {
|
||||||
warn!("Tried to set serial for unknown window {window:?}");
|
warn!("Tried to set serial for unknown window {window:?}");
|
||||||
return;
|
return;
|
||||||
|
|
@ -714,7 +975,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
self.world.insert(id, (SurfaceSerial(serial),)).unwrap();
|
self.world.insert(id, (SurfaceSerial(serial),)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_change_position(&self, window: x::Window) -> bool {
|
fn can_change_position(&self, window: x::Window) -> bool {
|
||||||
let Some(win) = self
|
let Some(win) = self
|
||||||
.windows
|
.windows
|
||||||
.get(&window)
|
.get(&window)
|
||||||
|
|
@ -728,7 +989,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
!win.mapped || win.attrs.is_popup
|
!win.mapped || win.attrs.is_popup
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reconfigure_window(&mut self, event: x::ConfigureNotifyEvent) {
|
fn reconfigure_window(&mut self, event: x::ConfigureNotifyEvent) {
|
||||||
let Some((mut win, data)) = self
|
let Some((mut win, data)) = self
|
||||||
.windows
|
.windows
|
||||||
.get(&event.window())
|
.get(&event.window())
|
||||||
|
|
@ -787,7 +1048,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_window(&mut self, window: x::Window) {
|
fn map_window(&mut self, window: x::Window) {
|
||||||
debug!("mapping {window:?}");
|
debug!("mapping {window:?}");
|
||||||
|
|
||||||
let Some(mut win) = self
|
let Some(mut win) = self
|
||||||
|
|
@ -804,7 +1065,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
win.mapped = true;
|
win.mapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unmap_window(&mut self, window: x::Window) {
|
fn unmap_window(&mut self, window: x::Window) {
|
||||||
let entity = self.windows.get(&window).copied();
|
let entity = self.windows.get(&window).copied();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -832,7 +1093,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_fullscreen(&mut self, window: x::Window, state: super::xstate::SetState) {
|
fn set_fullscreen(&mut self, window: x::Window, state: super::xstate::SetState) {
|
||||||
let Some(data) = self
|
let Some(data) = self
|
||||||
.windows
|
.windows
|
||||||
.get(&window)
|
.get(&window)
|
||||||
|
|
@ -867,7 +1128,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_transient_for(&mut self, window: x::Window, parent: x::Window) {
|
fn set_transient_for(&mut self, window: x::Window, parent: x::Window) {
|
||||||
let Some(mut win) = self
|
let Some(mut win) = self
|
||||||
.windows
|
.windows
|
||||||
.get(&window)
|
.get(&window)
|
||||||
|
|
@ -881,7 +1142,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
win.attrs.transient_for = Some(parent);
|
win.attrs.transient_for = Some(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn activate_window(&mut self, window: x::Window) {
|
fn activate_window(&mut self, window: x::Window) {
|
||||||
let Some(activation_state) = self.activation_state.as_ref() else {
|
let Some(activation_state) = self.activation_state.as_ref() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -918,7 +1179,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy_window(&mut self, window: x::Window) {
|
fn destroy_window(&mut self, window: x::Window) {
|
||||||
if let Some(id) = self.windows.remove(&window) {
|
if let Some(id) = self.windows.remove(&window) {
|
||||||
self.world.remove::<(x::Window, WindowData)>(id).unwrap();
|
self.world.remove::<(x::Window, WindowData)>(id).unwrap();
|
||||||
if self.world.entity(id).unwrap().is_empty() {
|
if self.world.entity(id).unwrap().is_empty() {
|
||||||
|
|
@ -927,7 +1188,7 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_copy_paste_source(&mut self, selection: &Rc<C::X11Selection>) {
|
fn set_copy_paste_source(&mut self, selection: &Rc<S>) {
|
||||||
if let Some(d) = &mut self.clipboard_data {
|
if let Some(d) = &mut self.clipboard_data {
|
||||||
let src = d
|
let src = d
|
||||||
.manager
|
.manager
|
||||||
|
|
@ -950,129 +1211,11 @@ impl<C: XConnection> ServerState<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
fn new_global_scale(&mut self) -> Option<f64> {
|
||||||
if let Some(r) = self.queue.prepare_read() {
|
|
||||||
let fd = r.connection_fd();
|
|
||||||
let pollfd = PollFd::new(&fd, PollFlags::IN);
|
|
||||||
if poll(&mut [pollfd], 0).unwrap() > 0 {
|
|
||||||
let _ = r.read();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.queue
|
|
||||||
.dispatch_pending(&mut self.world)
|
|
||||||
.expect("Failed dispatching client side Wayland events");
|
|
||||||
self.handle_clientside_events();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_clientside_events(&mut self) {
|
|
||||||
self.handle_new_globals();
|
|
||||||
|
|
||||||
for (target, event) in self.world.read_events() {
|
|
||||||
if !self.world.contains(target) {
|
|
||||||
warn!("could not handle clientside event: stale object");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
event.handle(target, self);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.global_offset_updated {
|
|
||||||
if self.global_output_offset.x.owner.is_none()
|
|
||||||
|| self.global_output_offset.y.owner.is_none()
|
|
||||||
{
|
|
||||||
self.calc_global_output_offset();
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!(
|
|
||||||
"updated global output offset: {}x{}",
|
|
||||||
self.global_output_offset.x.value, self.global_output_offset.y.value
|
|
||||||
);
|
|
||||||
for (e, _) in self.world.query::<&WlOutput>().iter() {
|
|
||||||
event::update_global_output_offset(
|
|
||||||
e,
|
|
||||||
&self.global_output_offset,
|
|
||||||
&self.world,
|
|
||||||
&mut self.connection,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
self.global_offset_updated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.updated_outputs.is_empty() {
|
|
||||||
for output in self.updated_outputs.drain(..) {
|
|
||||||
let output_scale = self.world.get::<&OutputScaleFactor>(output).unwrap();
|
|
||||||
if matches!(*output_scale, OutputScaleFactor::Output(..)) {
|
|
||||||
let mut surface_query = self
|
|
||||||
.world
|
|
||||||
.query::<(&OnOutput, &mut SurfaceScaleFactor)>()
|
|
||||||
.with::<(&WindowData, &WlSurface)>();
|
|
||||||
|
|
||||||
let mut surfaces = vec![];
|
|
||||||
for (surface, (OnOutput(s_output), surface_scale)) in surface_query.iter() {
|
|
||||||
if *s_output == output {
|
|
||||||
surface_scale.0 = output_scale.get();
|
|
||||||
surfaces.push(surface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(surface_query);
|
|
||||||
for surface in surfaces {
|
|
||||||
update_surface_viewport(self.world.query_one(surface).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut mixed_scale = false;
|
|
||||||
let mut scale;
|
|
||||||
|
|
||||||
let mut outputs = self.world.query_mut::<&OutputScaleFactor>().into_iter();
|
|
||||||
let (_, output_scale) = outputs.next().unwrap();
|
|
||||||
|
|
||||||
scale = output_scale.get();
|
|
||||||
|
|
||||||
for (_, output_scale) in outputs {
|
|
||||||
if output_scale.get() != scale {
|
|
||||||
mixed_scale = true;
|
|
||||||
scale = scale.min(output_scale.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if mixed_scale {
|
|
||||||
warn!("Mixed output scales detected, choosing to give apps the smallest detected scale ({scale}x)");
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("Using new scale {scale}");
|
|
||||||
self.new_scale = Some(scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
if let Some(FocusData {
|
|
||||||
window,
|
|
||||||
output_name,
|
|
||||||
}) = self.to_focus.take()
|
|
||||||
{
|
|
||||||
let conn = self.connection.as_mut().unwrap();
|
|
||||||
debug!("focusing window {window:?}");
|
|
||||||
conn.focus_window(window, output_name);
|
|
||||||
self.last_focused_toplevel = Some(window);
|
|
||||||
} else if self.unfocus {
|
|
||||||
let conn = self.connection.as_mut().unwrap();
|
|
||||||
conn.focus_window(x::WINDOW_NONE, None);
|
|
||||||
}
|
|
||||||
self.unfocus = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.handle_clipboard_events();
|
|
||||||
self.handle_activations();
|
|
||||||
self.queue
|
|
||||||
.flush()
|
|
||||||
.expect("Failed flushing clientside events");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_global_scale(&mut self) -> Option<f64> {
|
|
||||||
self.new_scale.take()
|
self.new_scale.take()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_selection(&mut self) -> Option<ForeignSelection> {
|
fn new_selection(&mut self) -> Option<ForeignSelection> {
|
||||||
self.clipboard_data.as_mut().and_then(|c| {
|
self.clipboard_data.as_mut().and_then(|c| {
|
||||||
c.source.take().and_then(|s| match s {
|
c.source.take().and_then(|s| match s {
|
||||||
CopyPasteData::Foreign(f) => Some(f),
|
CopyPasteData::Foreign(f) => Some(f),
|
||||||
|
|
@ -1367,17 +1510,6 @@ impl<C: XConnection> ServerState<C> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close_x_window(&mut self, window: x::Window) {
|
|
||||||
debug!("sending close request to {window:?}");
|
|
||||||
self.connection.as_mut().unwrap().close_window(window);
|
|
||||||
if self.last_focused_toplevel == Some(window) {
|
|
||||||
self.last_focused_toplevel.take();
|
|
||||||
}
|
|
||||||
if self.last_hovered == Some(window) {
|
|
||||||
self.last_hovered.take();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
|
|
@ -1406,7 +1538,7 @@ impl ForeignSelection {
|
||||||
state: &ServerState<impl XConnection>,
|
state: &ServerState<impl XConnection>,
|
||||||
) -> Vec<u8> {
|
) -> Vec<u8> {
|
||||||
let mut pipe = self.inner.receive(mime_type).unwrap();
|
let mut pipe = self.inner.receive(mime_type).unwrap();
|
||||||
state.queue.flush().unwrap();
|
state.inner.queue.flush().unwrap();
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
pipe.read_to_end(&mut data).unwrap();
|
pipe.read_to_end(&mut data).unwrap();
|
||||||
data
|
data
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{ServerState, WindowDims};
|
use super::{InnerServerState, ServerState, WindowDims};
|
||||||
use crate::xstate::{SetState, WinSize, WmName};
|
use crate::xstate::{SetState, WinSize, WmName};
|
||||||
use rustix::event::{poll, PollFd, PollFlags};
|
use rustix::event::{poll, PollFd, PollFlags};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
@ -184,6 +184,7 @@ impl Default for FakeXConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FakeX11Selection = Vec<testwl::PasteData>;
|
||||||
impl crate::X11Selection for Vec<testwl::PasteData> {
|
impl crate::X11Selection for Vec<testwl::PasteData> {
|
||||||
fn mime_types(&self) -> Vec<&str> {
|
fn mime_types(&self) -> Vec<&str> {
|
||||||
self.iter().map(|data| data.mime_type.as_str()).collect()
|
self.iter().map(|data| data.mime_type.as_str()).collect()
|
||||||
|
|
@ -204,7 +205,7 @@ impl crate::X11Selection for Vec<testwl::PasteData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::XConnection for FakeXConnection {
|
impl super::XConnection for FakeXConnection {
|
||||||
type X11Selection = Vec<testwl::PasteData>;
|
type X11Selection = FakeX11Selection;
|
||||||
fn root_window(&self) -> Window {
|
fn root_window(&self) -> Window {
|
||||||
self.root
|
self.root
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +260,7 @@ struct TestFixture {
|
||||||
/// Our connection to satellite - i.e., where Xwayland sends requests to
|
/// Our connection to satellite - i.e., where Xwayland sends requests to
|
||||||
xwls_connection: Arc<Connection>,
|
xwls_connection: Arc<Connection>,
|
||||||
/// Satellite's display - must dispatch this for our server state to advance
|
/// Satellite's display - must dispatch this for our server state to advance
|
||||||
xwls_display: Display<FakeServerState>,
|
xwls_display: Display<InnerServerState<FakeX11Selection>>,
|
||||||
surface_serial: u64,
|
surface_serial: u64,
|
||||||
registry: TestObject<WlRegistry>,
|
registry: TestObject<WlRegistry>,
|
||||||
}
|
}
|
||||||
|
|
@ -379,7 +380,7 @@ impl TestFixture {
|
||||||
if let Some(pre_connect) = options.pre_connect {
|
if let Some(pre_connect) = options.pre_connect {
|
||||||
pre_connect.call(&mut testwl);
|
pre_connect.call(&mut testwl);
|
||||||
}
|
}
|
||||||
let display = Display::<FakeServerState>::new().unwrap();
|
let display = Display::new().unwrap();
|
||||||
testwl.connect(server_s);
|
testwl.connect(server_s);
|
||||||
// Handle initial globals roundtrip setup requirement
|
// Handle initial globals roundtrip setup requirement
|
||||||
let thread = std::thread::spawn(move || {
|
let thread = std::thread::spawn(move || {
|
||||||
|
|
@ -513,7 +514,7 @@ impl TestFixture {
|
||||||
|
|
||||||
// Have satellite dispatch our requests
|
// Have satellite dispatch our requests
|
||||||
self.xwls_display
|
self.xwls_display
|
||||||
.dispatch_clients(&mut self.satellite)
|
.dispatch_clients(self.satellite.inner_mut())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.xwls_display.flush_clients().unwrap();
|
self.xwls_display.flush_clients().unwrap();
|
||||||
|
|
||||||
|
|
@ -1428,12 +1429,12 @@ fn raise_window_on_pointer_event() {
|
||||||
f.testwl.move_pointer_to(id2, 0.0, 0.0);
|
f.testwl.move_pointer_to(id2, 0.0, 0.0);
|
||||||
f.run();
|
f.run();
|
||||||
assert_eq!(f.connection().focused_window, Some(win2));
|
assert_eq!(f.connection().focused_window, Some(win2));
|
||||||
assert_eq!(f.satellite.last_hovered, Some(win2));
|
assert_eq!(f.satellite.inner.last_hovered, Some(win2));
|
||||||
|
|
||||||
f.testwl.move_pointer_to(id1, 0.0, 0.0);
|
f.testwl.move_pointer_to(id1, 0.0, 0.0);
|
||||||
f.run();
|
f.run();
|
||||||
assert_eq!(f.connection().focused_window, Some(win2));
|
assert_eq!(f.connection().focused_window, Some(win2));
|
||||||
assert_eq!(f.satellite.last_hovered, Some(win1));
|
assert_eq!(f.satellite.inner.last_hovered, Some(win1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -1450,7 +1451,7 @@ fn override_redirect_choose_hover_window() {
|
||||||
|
|
||||||
f.testwl.move_pointer_to(id1, 0.0, 0.0);
|
f.testwl.move_pointer_to(id1, 0.0, 0.0);
|
||||||
f.run();
|
f.run();
|
||||||
assert_eq!(f.satellite.last_hovered, Some(win1));
|
assert_eq!(f.satellite.inner.last_hovered, Some(win1));
|
||||||
|
|
||||||
let win3 = unsafe { Window::new(3) };
|
let win3 = unsafe { Window::new(3) };
|
||||||
let (buffer, surface) = comp.create_surface();
|
let (buffer, surface) = comp.create_surface();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue