mirror of
https://github.com/wez/wezterm.git
synced 2024-11-29 21:44:24 +03:00
Update SCTK to 0.18
This commit is contained in:
parent
0c97ace3cb
commit
aab3835f1a
100
Cargo.lock
generated
100
Cargo.lock
generated
@ -1274,6 +1274,12 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cursor-icon"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "d3d12"
|
name = "d3d12"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -3218,18 +3224,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.5.10"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
|
checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap2"
|
name = "memmap2"
|
||||||
version = "0.8.0"
|
version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed"
|
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@ -4294,15 +4300,6 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quick-xml"
|
|
||||||
version = "0.28.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-xml"
|
name = "quick-xml"
|
||||||
version = "0.30.0"
|
version = "0.30.0"
|
||||||
@ -5055,23 +5052,25 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smithay-client-toolkit"
|
name = "smithay-client-toolkit"
|
||||||
version = "0.17.0"
|
version = "0.18.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1476c3d89bb67079264b88aaf4f14358353318397e083b7c4e8c14517f55de7"
|
checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 2.4.2",
|
||||||
"dlib",
|
"cursor-icon",
|
||||||
"lazy_static",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"memmap2 0.5.10",
|
"memmap2 0.9.4",
|
||||||
"nix 0.26.4",
|
"rustix 0.38.31",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
|
"wayland-csd-frame",
|
||||||
"wayland-cursor",
|
"wayland-cursor",
|
||||||
"wayland-protocols",
|
"wayland-protocols",
|
||||||
"wayland-protocols-wlr",
|
"wayland-protocols-wlr",
|
||||||
"wayland-scanner",
|
"wayland-scanner",
|
||||||
|
"xkeysym",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6125,14 +6124,13 @@ checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-backend"
|
name = "wayland-backend"
|
||||||
version = "0.1.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41b48e27457e8da3b2260ac60d0a94512f5cba36448679f3747c0865b7893ed8"
|
checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"downcast-rs",
|
"downcast-rs",
|
||||||
"io-lifetimes",
|
"rustix 0.38.31",
|
||||||
"nix 0.26.4",
|
|
||||||
"scoped-tls",
|
"scoped-tls",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"wayland-sys",
|
"wayland-sys",
|
||||||
@ -6140,32 +6138,43 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-client"
|
name = "wayland-client"
|
||||||
version = "0.30.2"
|
version = "0.31.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "489c9654770f674fc7e266b3c579f4053d7551df0ceb392f153adb1f9ed06ac8"
|
checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 2.4.2",
|
||||||
"nix 0.26.4",
|
"rustix 0.38.31",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-scanner",
|
"wayland-scanner",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-cursor"
|
name = "wayland-csd-frame"
|
||||||
version = "0.30.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d0c3a0d5b4b688b07b0442362d3ed6bf04724fcc16cd69ab6285b90dbc487aa"
|
checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nix 0.26.4",
|
"bitflags 2.4.2",
|
||||||
|
"cursor-icon",
|
||||||
|
"wayland-backend",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wayland-cursor"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba"
|
||||||
|
dependencies = [
|
||||||
|
"rustix 0.38.31",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
"xcursor",
|
"xcursor",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-egl"
|
name = "wayland-egl"
|
||||||
version = "0.30.0"
|
version = "0.32.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1187695fe81c3153c3163f9d2953149f638c5d7dbc6fe988914ca3f4961e28ed"
|
checksum = "355f652e5a24ae02d2ad536c8fc2d3dcc6c2bd635027cd6103a193e7d75eeda2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-sys",
|
"wayland-sys",
|
||||||
@ -6173,11 +6182,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-protocols"
|
name = "wayland-protocols"
|
||||||
version = "0.30.1"
|
version = "0.31.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b28101e5ca94f70461a6c2d610f76d85ad223d042dd76585ab23d3422dd9b4d"
|
checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 2.4.2",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
"wayland-scanner",
|
"wayland-scanner",
|
||||||
@ -6185,11 +6194,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-protocols-wlr"
|
name = "wayland-protocols-wlr"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fce991093320e4a6a525876e6b629ab24da25f9baef0c2e0080ad173ec89588a"
|
checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 2.4.2",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
"wayland-protocols",
|
"wayland-protocols",
|
||||||
@ -6198,20 +6207,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-scanner"
|
name = "wayland-scanner"
|
||||||
version = "0.30.1"
|
version = "0.31.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9b873b257fbc32ec909c0eb80dea312076a67014e65e245f5eb69a6b8ab330e"
|
checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quick-xml 0.28.2",
|
"quick-xml 0.31.0",
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wayland-sys"
|
name = "wayland-sys"
|
||||||
version = "0.30.1"
|
version = "0.31.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06"
|
checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dlib",
|
"dlib",
|
||||||
"log",
|
"log",
|
||||||
@ -6881,6 +6890,7 @@ dependencies = [
|
|||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
"url",
|
"url",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
|
"wayland-csd-frame",
|
||||||
"wayland-egl",
|
"wayland-egl",
|
||||||
"wayland-protocols",
|
"wayland-protocols",
|
||||||
"wezterm-bidi",
|
"wezterm-bidi",
|
||||||
|
@ -15,7 +15,7 @@ k9 = "0.11.0"
|
|||||||
gl_generator = "0.14"
|
gl_generator = "0.14"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
wayland = ["wayland-client", "smithay-client-toolkit", "wayland-egl", "wayland-protocols"]
|
wayland = ["wayland-client", "smithay-client-toolkit", "wayland-egl", "wayland-protocols", "wayland-csd-frame"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-channel = "1.6"
|
async-channel = "1.6"
|
||||||
@ -81,10 +81,11 @@ xcb-imdkit = { version="0.3", git="https://github.com/wez/xcb-imdkit-rs.git", re
|
|||||||
zbus = "3.14"
|
zbus = "3.14"
|
||||||
zvariant = "3.15"
|
zvariant = "3.15"
|
||||||
|
|
||||||
smithay-client-toolkit = {version = "0.17.0", default-features=false, optional=true}
|
smithay-client-toolkit = {version = "0.18.1", default-features=false, optional=true}
|
||||||
wayland-protocols = {version="0.30", optional=true}
|
wayland-protocols = {version="0.31", optional=true}
|
||||||
wayland-client = {version="0.30", optional=true}
|
wayland-client = {version="0.31", optional=true}
|
||||||
wayland-egl = {version="0.30", optional=true}
|
wayland-egl = {version="0.32", optional=true}
|
||||||
|
wayland-csd-frame = { version = "0.3.0", optional = true}
|
||||||
|
|
||||||
[target.'cfg(target_os="macos")'.dependencies]
|
[target.'cfg(target_os="macos")'.dependencies]
|
||||||
cocoa = "0.25"
|
cocoa = "0.25"
|
||||||
|
@ -58,7 +58,11 @@ impl WaylandConnection {
|
|||||||
let mut events = Events::with_capacity(8);
|
let mut events = Events::with_capacity(8);
|
||||||
|
|
||||||
let wl_fd = {
|
let wl_fd = {
|
||||||
let read_guard = self.event_queue.borrow().prepare_read()?;
|
let read_guard = self
|
||||||
|
.event_queue
|
||||||
|
.borrow()
|
||||||
|
.prepare_read()
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("Failed to preapre event queue"))?;
|
||||||
read_guard.connection_fd().as_raw_fd()
|
read_guard.connection_fd().as_raw_fd()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,7 +104,7 @@ impl WaylandConnection {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(guard) = event_q.prepare_read() {
|
if let Some(guard) = event_q.prepare_read() {
|
||||||
if let Err(err) = guard.read() {
|
if let Err(err) = guard.read() {
|
||||||
log::trace!("Event Q error: {:?}", err);
|
log::trace!("Event Q error: {:?}", err);
|
||||||
if let WaylandError::Protocol(perr) = err {
|
if let WaylandError::Protocol(perr) = err {
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
use anyhow::{anyhow, Error, bail};
|
use anyhow::{anyhow, bail};
|
||||||
use filedescriptor::{FileDescriptor, Pipe};
|
|
||||||
use smithay_client_toolkit as toolkit;
|
use smithay_client_toolkit as toolkit;
|
||||||
use toolkit::globals::GlobalData;
|
|
||||||
use wayland_client::{Dispatch, event_created_child};
|
|
||||||
use wayland_client::globals::{GlobalList, BindError};
|
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_device_manager_v1::ZwpPrimarySelectionDeviceManagerV1;
|
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_device_v1::{ZwpPrimarySelectionDeviceV1, self, Event as PrimarySelectionDeviceEvent};
|
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_offer_v1::{ZwpPrimarySelectionOfferV1, Event as PrimarySelectionOfferEvent};
|
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_source_v1::{ZwpPrimarySelectionSourceV1, Event as PrimarySelectionSourceEvent};
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd};
|
use std::os::fd::AsRawFd;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use toolkit::reexports::client::protocol::wl_data_offer::WlDataOffer;
|
use toolkit::data_device_manager::data_offer::SelectionOffer;
|
||||||
|
use toolkit::data_device_manager::{ReadPipe, WritePipe};
|
||||||
|
use toolkit::primary_selection::device::PrimarySelectionDeviceHandler;
|
||||||
|
use toolkit::primary_selection::selection::PrimarySelectionSourceHandler;
|
||||||
|
use wayland_client::{Connection as WConnection, QueueHandle};
|
||||||
|
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_device_v1::ZwpPrimarySelectionDeviceV1;
|
||||||
|
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1;
|
||||||
|
|
||||||
use crate::{Clipboard, ConnectionOps};
|
use crate::{Clipboard, ConnectionOps};
|
||||||
|
|
||||||
@ -20,7 +18,7 @@ use super::state::WaylandState;
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct CopyAndPaste {
|
pub struct CopyAndPaste {
|
||||||
data_offer: Option<WlDataOffer>,
|
data_offer: Option<SelectionOffer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for CopyAndPaste {
|
impl std::fmt::Debug for CopyAndPaste {
|
||||||
@ -36,37 +34,31 @@ impl CopyAndPaste {
|
|||||||
Arc::new(Mutex::new(Default::default()))
|
Arc::new(Mutex::new(Default::default()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_clipboard_data(
|
pub(super) fn get_clipboard_data(&mut self, clipboard: Clipboard) -> anyhow::Result<ReadPipe> {
|
||||||
&mut self,
|
|
||||||
clipboard: Clipboard,
|
|
||||||
) -> anyhow::Result<FileDescriptor> {
|
|
||||||
let conn = crate::Connection::get().unwrap().wayland();
|
let conn = crate::Connection::get().unwrap().wayland();
|
||||||
let wayland_state = conn.wayland_state.borrow();
|
let wayland_state = conn.wayland_state.borrow();
|
||||||
let primary_selection = if let Clipboard::PrimarySelection = clipboard {
|
let primary_selection = if let Clipboard::PrimarySelection = clipboard {
|
||||||
wayland_state.primary_selection_manager.as_ref()
|
wayland_state.primary_selection_device.as_ref()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
match primary_selection {
|
match primary_selection {
|
||||||
Some(primary_selection) => {
|
Some(primary_selection) => {
|
||||||
let inner = primary_selection.inner.lock().unwrap();
|
let offer = primary_selection
|
||||||
let offer = inner
|
.data()
|
||||||
.offer
|
.selection_offer()
|
||||||
.as_ref()
|
|
||||||
.ok_or_else(|| anyhow!("no primary selection offer"))?;
|
.ok_or_else(|| anyhow!("no primary selection offer"))?;
|
||||||
let pipe = Pipe::new().map_err(Error::msg)?;
|
let pipe = offer.receive(TEXT_MIME_TYPE.to_string())?;
|
||||||
offer.receive(TEXT_MIME_TYPE.to_string(), pipe.write.as_raw_fd());
|
Ok(pipe)
|
||||||
Ok(pipe.read)
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let offer = self
|
let offer = self
|
||||||
.data_offer
|
.data_offer
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or_else(|| anyhow!("no data offer"))?;
|
.ok_or_else(|| anyhow!("no data offer"))?;
|
||||||
let pipe = Pipe::new().map_err(Error::msg)?;
|
let pipe = offer.receive(TEXT_MIME_TYPE.to_string())?;
|
||||||
offer.receive(TEXT_MIME_TYPE.to_string(), pipe.write.as_raw_fd());
|
Ok(pipe)
|
||||||
Ok(pipe.read)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,18 +70,16 @@ impl CopyAndPaste {
|
|||||||
let last_serial = *wayland_state.last_serial.borrow();
|
let last_serial = *wayland_state.last_serial.borrow();
|
||||||
|
|
||||||
let primary_selection = if let Clipboard::PrimarySelection = clipboard {
|
let primary_selection = if let Clipboard::PrimarySelection = clipboard {
|
||||||
wayland_state.primary_selection_manager.as_ref()
|
wayland_state.primary_selection_device.as_ref()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
match primary_selection {
|
match primary_selection {
|
||||||
Some(primary_selection) => {
|
Some(selection_device) => {
|
||||||
let manager = &primary_selection.manager;
|
let manager = wayland_state.primary_selection_manager.as_ref().unwrap();
|
||||||
let selection_device = wayland_state.primary_select_device.as_ref().unwrap();
|
let source = manager.create_selection_source(&qh, [TEXT_MIME_TYPE]);
|
||||||
let source = manager.create_source(&qh, PrimarySelectionManagerData::default());
|
source.set_selection(&selection_device, last_serial);
|
||||||
source.offer(TEXT_MIME_TYPE.to_string());
|
|
||||||
selection_device.set_selection(Some(&source), last_serial);
|
|
||||||
wayland_state
|
wayland_state
|
||||||
.primary_selection_source
|
.primary_selection_source
|
||||||
.replace((source, data));
|
.replace((source, data));
|
||||||
@ -105,7 +95,7 @@ impl CopyAndPaste {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn confirm_selection(&mut self, offer: WlDataOffer) {
|
pub(super) fn confirm_selection(&mut self, offer: SelectionOffer) {
|
||||||
self.data_offer.replace(offer);
|
self.data_offer.replace(offer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,14 +112,17 @@ impl WaylandState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn write_selection_to_pipe(fd: FileDescriptor, text: &str) {
|
pub(super) fn write_selection_to_pipe(pipe: WritePipe, text: &str) {
|
||||||
if let Err(e) = write_pipe_with_timeout(fd, text.as_bytes()) {
|
if let Err(e) = write_pipe_with_timeout(pipe, text.as_bytes()) {
|
||||||
log::error!("while sending primary selection to pipe: {}", e);
|
log::error!("while sending primary selection to pipe: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_pipe_with_timeout(mut file: FileDescriptor, data: &[u8]) -> anyhow::Result<()> {
|
fn write_pipe_with_timeout(mut file: WritePipe, data: &[u8]) -> anyhow::Result<()> {
|
||||||
file.set_non_blocking(true)?;
|
// Set the file as non-blocking
|
||||||
|
unsafe {
|
||||||
|
libc::fcntl(file.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
|
||||||
|
}
|
||||||
let mut pfd = libc::pollfd {
|
let mut pfd = libc::pollfd {
|
||||||
fd: file.as_raw_fd(),
|
fd: file.as_raw_fd(),
|
||||||
events: libc::POLLOUT,
|
events: libc::POLLOUT,
|
||||||
@ -157,150 +150,43 @@ fn write_pipe_with_timeout(mut file: FileDescriptor, data: &[u8]) -> anyhow::Res
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smithay has their own primary selection handler in 0.18
|
impl PrimarySelectionSourceHandler for WaylandState {
|
||||||
// Some code borrowed from https://github.com/Smithay/client-toolkit/commit/4a5c4f59f640bc588a55277261bbed1bd2abea98
|
fn send_request(
|
||||||
pub(super) struct PrimarySelectionManagerState {
|
&mut self,
|
||||||
pub(super) manager: ZwpPrimarySelectionDeviceManagerV1,
|
_conn: &WConnection,
|
||||||
inner: Mutex<PrimaryInner>,
|
_qh: &QueueHandle<WaylandState>,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
|
||||||
struct PrimaryInner {
|
|
||||||
pending_offer: Option<ZwpPrimarySelectionOfferV1>,
|
|
||||||
offer: Option<ZwpPrimarySelectionOfferV1>,
|
|
||||||
valid_mime: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub(super) struct PrimarySelectionManagerData {}
|
|
||||||
|
|
||||||
impl PrimarySelectionManagerState {
|
|
||||||
pub(super) fn bind(
|
|
||||||
globals: &GlobalList,
|
|
||||||
queue_handle: &wayland_client::QueueHandle<WaylandState>,
|
|
||||||
) -> Result<Self, BindError> {
|
|
||||||
let manager = globals.bind(queue_handle, 1..=1, GlobalData)?;
|
|
||||||
Ok(Self {
|
|
||||||
manager,
|
|
||||||
inner: Mutex::new(PrimaryInner::default()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Dispatch<ZwpPrimarySelectionDeviceManagerV1, GlobalData, WaylandState>
|
|
||||||
for PrimarySelectionManagerState
|
|
||||||
{
|
|
||||||
fn event(
|
|
||||||
_state: &mut WaylandState,
|
|
||||||
_proxy: &ZwpPrimarySelectionDeviceManagerV1,
|
|
||||||
_event: <ZwpPrimarySelectionDeviceManagerV1 as wayland_client::Proxy>::Event,
|
|
||||||
_data: &GlobalData,
|
|
||||||
_conn: &wayland_client::Connection,
|
|
||||||
_qhandle: &wayland_client::QueueHandle<WaylandState>,
|
|
||||||
) {
|
|
||||||
unreachable!("primary selection manager has no events");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Dispatch<ZwpPrimarySelectionSourceV1, PrimarySelectionManagerData, WaylandState>
|
|
||||||
for PrimarySelectionManagerState
|
|
||||||
{
|
|
||||||
fn event(
|
|
||||||
state: &mut WaylandState,
|
|
||||||
source: &ZwpPrimarySelectionSourceV1,
|
source: &ZwpPrimarySelectionSourceV1,
|
||||||
event: <ZwpPrimarySelectionSourceV1 as wayland_client::Proxy>::Event,
|
mime_type: String,
|
||||||
_data: &PrimarySelectionManagerData,
|
write_pipe: WritePipe,
|
||||||
_conn: &wayland_client::Connection,
|
|
||||||
_qhandle: &wayland_client::QueueHandle<WaylandState>,
|
|
||||||
) {
|
) {
|
||||||
match event {
|
if mime_type != TEXT_MIME_TYPE {
|
||||||
PrimarySelectionSourceEvent::Send { mime_type, fd } => {
|
return;
|
||||||
if mime_type != TEXT_MIME_TYPE {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some((ps_source, data)) = &state.primary_selection_source {
|
|
||||||
if ps_source != source {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let fd = unsafe { FileDescriptor::from_raw_fd(fd.into_raw_fd()) };
|
|
||||||
write_selection_to_pipe(fd, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PrimarySelectionSourceEvent::Cancelled => {
|
|
||||||
state.primary_selection_source.take();
|
|
||||||
source.destroy();
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
|
if let Some((ps_source, data)) = &self.primary_selection_source {
|
||||||
|
if ps_source.inner() != source {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write_selection_to_pipe(write_pipe, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cancelled(
|
||||||
|
&mut self,
|
||||||
|
_conn: &WConnection,
|
||||||
|
_qh: &QueueHandle<WaylandState>,
|
||||||
|
source: &ZwpPrimarySelectionSourceV1,
|
||||||
|
) {
|
||||||
|
self.primary_selection_source.take();
|
||||||
|
source.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dispatch<ZwpPrimarySelectionOfferV1, PrimarySelectionManagerData, WaylandState>
|
impl PrimarySelectionDeviceHandler for WaylandState {
|
||||||
for PrimarySelectionManagerState
|
fn selection(
|
||||||
{
|
&mut self,
|
||||||
fn event(
|
_conn: &WConnection,
|
||||||
state: &mut WaylandState,
|
_qh: &QueueHandle<Self>,
|
||||||
_proxy: &ZwpPrimarySelectionOfferV1,
|
|
||||||
event: <ZwpPrimarySelectionOfferV1 as wayland_client::Proxy>::Event,
|
|
||||||
_data: &PrimarySelectionManagerData,
|
|
||||||
_conn: &wayland_client::Connection,
|
|
||||||
_qhandle: &wayland_client::QueueHandle<WaylandState>,
|
|
||||||
) {
|
|
||||||
match event {
|
|
||||||
PrimarySelectionOfferEvent::Offer { mime_type } => {
|
|
||||||
if mime_type == TEXT_MIME_TYPE {
|
|
||||||
let mgr = state.primary_selection_manager.as_ref().unwrap();
|
|
||||||
let mut inner = mgr.inner.lock().unwrap();
|
|
||||||
inner.valid_mime = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Dispatch<ZwpPrimarySelectionDeviceV1, PrimarySelectionManagerData, WaylandState>
|
|
||||||
for PrimarySelectionManagerState
|
|
||||||
{
|
|
||||||
event_created_child!(WaylandState, ZwpPrimarySelectionDeviceV1, [
|
|
||||||
zwp_primary_selection_device_v1::EVT_DATA_OFFER_OPCODE => (ZwpPrimarySelectionOfferV1, PrimarySelectionManagerData::default())
|
|
||||||
]);
|
|
||||||
|
|
||||||
fn event(
|
|
||||||
state: &mut WaylandState,
|
|
||||||
_primary_selection_device: &ZwpPrimarySelectionDeviceV1,
|
_primary_selection_device: &ZwpPrimarySelectionDeviceV1,
|
||||||
event: <ZwpPrimarySelectionDeviceV1 as wayland_client::Proxy>::Event,
|
|
||||||
_data: &PrimarySelectionManagerData,
|
|
||||||
_conn: &wayland_client::Connection,
|
|
||||||
_qhandle: &wayland_client::QueueHandle<WaylandState>,
|
|
||||||
) {
|
) {
|
||||||
let psm = state.primary_selection_manager.as_ref().unwrap();
|
|
||||||
let mut inner = psm.inner.lock().unwrap();
|
|
||||||
match event {
|
|
||||||
PrimarySelectionDeviceEvent::DataOffer { offer } => {
|
|
||||||
inner.pending_offer = Some(offer);
|
|
||||||
}
|
|
||||||
PrimarySelectionDeviceEvent::Selection { id } => {
|
|
||||||
if !inner.valid_mime {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(offer) = inner.offer.take() {
|
|
||||||
offer.destroy();
|
|
||||||
}
|
|
||||||
if id == inner.pending_offer {
|
|
||||||
inner.offer = inner.pending_offer.take();
|
|
||||||
} else {
|
|
||||||
// Remove the pending offer, assign the new delivered one.
|
|
||||||
if let Some(offer) = inner.pending_offer.take() {
|
|
||||||
offer.destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
inner.offer = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
use std::os::fd::{FromRawFd, IntoRawFd};
|
use smithay_client_toolkit::data_device_manager::data_device::DataDeviceHandler;
|
||||||
|
|
||||||
use filedescriptor::FileDescriptor;
|
|
||||||
use smithay_client_toolkit::data_device_manager::data_device::{
|
|
||||||
DataDevice, DataDeviceDataExt, DataDeviceHandler,
|
|
||||||
};
|
|
||||||
use smithay_client_toolkit::data_device_manager::data_offer::DataOfferHandler;
|
use smithay_client_toolkit::data_device_manager::data_offer::DataOfferHandler;
|
||||||
use smithay_client_toolkit::data_device_manager::data_source::DataSourceHandler;
|
use smithay_client_toolkit::data_device_manager::data_source::DataSourceHandler;
|
||||||
use smithay_client_toolkit::data_device_manager::WritePipe;
|
use smithay_client_toolkit::data_device_manager::WritePipe;
|
||||||
|
use wayland_client::protocol::wl_data_device::WlDataDevice;
|
||||||
use wayland_client::protocol::wl_data_device_manager::DndAction;
|
use wayland_client::protocol::wl_data_device_manager::DndAction;
|
||||||
use wayland_client::Proxy;
|
use wayland_client::Proxy;
|
||||||
|
|
||||||
@ -26,19 +22,25 @@ impl DataDeviceHandler for WaylandState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_conn: &wayland_client::Connection,
|
_conn: &wayland_client::Connection,
|
||||||
_qh: &wayland_client::QueueHandle<Self>,
|
_qh: &wayland_client::QueueHandle<Self>,
|
||||||
data_device: DataDevice,
|
data_device: &WlDataDevice,
|
||||||
) {
|
) {
|
||||||
let mut drag_offer = data_device.drag_offer().unwrap();
|
let data = match self.data_device {
|
||||||
|
Some(ref dv) if dv.inner() == data_device => dv.data(),
|
||||||
|
_ => {
|
||||||
|
log::warn!("No existing device manager for {:?}", data_device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let drag_offer = data.drag_offer().unwrap();
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"Data offer entered: {:?}, mime_types: {:?}",
|
"Data offer entered: {:?}, mime_types: {:?}",
|
||||||
drag_offer,
|
drag_offer,
|
||||||
data_device.drag_mime_types()
|
drag_offer.with_mime_types(|m| m.iter().cloned().collect::<Vec<_>>())
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(m) = data_device
|
if let Some(m) =
|
||||||
.drag_mime_types()
|
drag_offer.with_mime_types(|m| m.iter().find(|s| *s == URI_MIME_TYPE).cloned())
|
||||||
.iter()
|
|
||||||
.find(|s| *s == URI_MIME_TYPE)
|
|
||||||
{
|
{
|
||||||
drag_offer.accept_mime_type(*self.last_serial.borrow(), Some(m.clone()));
|
drag_offer.accept_mime_type(*self.last_serial.borrow(), Some(m.clone()));
|
||||||
}
|
}
|
||||||
@ -54,8 +56,8 @@ impl DataDeviceHandler for WaylandState {
|
|||||||
.lock()
|
.lock()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let offer = drag_offer.inner().clone();
|
let offer = drag_offer;
|
||||||
let window_id = SurfaceUserData::from_wl(&drag_offer.surface).window_id;
|
let window_id = SurfaceUserData::from_wl(&offer.surface).window_id;
|
||||||
|
|
||||||
pstate.drag_and_drop.offer = Some(SurfaceAndOffer { window_id, offer });
|
pstate.drag_and_drop.offer = Some(SurfaceAndOffer { window_id, offer });
|
||||||
}
|
}
|
||||||
@ -64,7 +66,7 @@ impl DataDeviceHandler for WaylandState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_conn: &wayland_client::Connection,
|
_conn: &wayland_client::Connection,
|
||||||
_qh: &wayland_client::QueueHandle<Self>,
|
_qh: &wayland_client::QueueHandle<Self>,
|
||||||
_data_device: DataDevice,
|
_data_device: &WlDataDevice,
|
||||||
) {
|
) {
|
||||||
let pointer = self.pointer.as_mut().unwrap();
|
let pointer = self.pointer.as_mut().unwrap();
|
||||||
let mut pstate = pointer
|
let mut pstate = pointer
|
||||||
@ -83,7 +85,7 @@ impl DataDeviceHandler for WaylandState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_conn: &wayland_client::Connection,
|
_conn: &wayland_client::Connection,
|
||||||
_qh: &wayland_client::QueueHandle<Self>,
|
_qh: &wayland_client::QueueHandle<Self>,
|
||||||
_data_device: DataDevice,
|
_data_device: &WlDataDevice,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,19 +93,21 @@ impl DataDeviceHandler for WaylandState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_conn: &wayland_client::Connection,
|
_conn: &wayland_client::Connection,
|
||||||
_qh: &wayland_client::QueueHandle<Self>,
|
_qh: &wayland_client::QueueHandle<Self>,
|
||||||
data_device: DataDevice,
|
data_device: &WlDataDevice,
|
||||||
) {
|
) {
|
||||||
let mime_types = data_device.selection_mime_types();
|
let selection = match self.data_device {
|
||||||
if !mime_types.iter().any(|s| s == TEXT_MIME_TYPE) {
|
Some(ref dv) if dv.inner() == data_device => dv.data().selection_offer(),
|
||||||
return;
|
_ => {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(offer) = data_device.selection_offer() {
|
if let Some(offer) = selection {
|
||||||
|
if !offer.with_mime_types(|m| m.iter().any(|s| *s == TEXT_MIME_TYPE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if let Some(copy_and_paste) = self.resolve_copy_and_paste() {
|
if let Some(copy_and_paste) = self.resolve_copy_and_paste() {
|
||||||
copy_and_paste
|
copy_and_paste.lock().unwrap().confirm_selection(offer);
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.confirm_selection(offer.inner().clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,7 +116,7 @@ impl DataDeviceHandler for WaylandState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_conn: &wayland_client::Connection,
|
_conn: &wayland_client::Connection,
|
||||||
_qh: &wayland_client::QueueHandle<Self>,
|
_qh: &wayland_client::QueueHandle<Self>,
|
||||||
_data_device: DataDevice,
|
_data_device: &WlDataDevice,
|
||||||
) {
|
) {
|
||||||
let pointer = self.pointer.as_mut().unwrap();
|
let pointer = self.pointer.as_mut().unwrap();
|
||||||
let mut pstate = pointer
|
let mut pstate = pointer
|
||||||
@ -135,22 +139,6 @@ impl DataDeviceHandler for WaylandState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DataOfferHandler for WaylandState {
|
impl DataOfferHandler for WaylandState {
|
||||||
fn offer(
|
|
||||||
&mut self,
|
|
||||||
_conn: &wayland_client::Connection,
|
|
||||||
_qh: &wayland_client::QueueHandle<Self>,
|
|
||||||
offer: &mut smithay_client_toolkit::data_device_manager::data_offer::DataDeviceOffer,
|
|
||||||
mime_type: String,
|
|
||||||
) {
|
|
||||||
log::trace!("Received offer with mime type: {mime_type}");
|
|
||||||
if mime_type == TEXT_MIME_TYPE {
|
|
||||||
offer.accept_mime_type(*self.last_serial.borrow(), Some(mime_type));
|
|
||||||
} else {
|
|
||||||
// Refuse other mime types
|
|
||||||
offer.accept_mime_type(*self.last_serial.borrow(), None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore drag and drop events
|
// Ignore drag and drop events
|
||||||
fn source_actions(
|
fn source_actions(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -198,7 +186,6 @@ impl DataSourceHandler for WaylandState {
|
|||||||
if cp_source.inner() != source {
|
if cp_source.inner() != source {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let fd = unsafe { FileDescriptor::from_raw_fd(fd.into_raw_fd()) };
|
|
||||||
write_selection_to_pipe(fd, data);
|
write_selection_to_pipe(fd, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use crate::wayland::read_pipe_with_timeout;
|
use crate::wayland::read_pipe_with_timeout;
|
||||||
use crate::ConnectionOps;
|
use crate::ConnectionOps;
|
||||||
use filedescriptor::{FileDescriptor, Pipe};
|
|
||||||
use smithay_client_toolkit as toolkit;
|
use smithay_client_toolkit as toolkit;
|
||||||
use std::os::unix::io::AsRawFd;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use toolkit::reexports::client::protocol::wl_data_offer::WlDataOffer;
|
use toolkit::data_device_manager::data_offer::DragOffer;
|
||||||
|
use toolkit::data_device_manager::ReadPipe;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use super::data_device::URI_MIME_TYPE;
|
use super::data_device::URI_MIME_TYPE;
|
||||||
@ -17,12 +16,12 @@ pub struct DragAndDrop {
|
|||||||
|
|
||||||
pub(super) struct SurfaceAndOffer {
|
pub(super) struct SurfaceAndOffer {
|
||||||
pub(super) window_id: usize,
|
pub(super) window_id: usize,
|
||||||
pub(super) offer: WlDataOffer,
|
pub(super) offer: DragOffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct SurfaceAndPipe {
|
pub(super) struct SurfaceAndPipe {
|
||||||
pub(super) window_id: usize,
|
pub(super) window_id: usize,
|
||||||
pub(super) read: FileDescriptor,
|
pub(super) read: ReadPipe,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DragAndDrop {
|
impl DragAndDrop {
|
||||||
@ -30,16 +29,15 @@ impl DragAndDrop {
|
|||||||
/// returning that surface and pipe descriptor.
|
/// returning that surface and pipe descriptor.
|
||||||
pub(super) fn create_pipe_for_drop(&mut self) -> Option<SurfaceAndPipe> {
|
pub(super) fn create_pipe_for_drop(&mut self) -> Option<SurfaceAndPipe> {
|
||||||
let SurfaceAndOffer { window_id, offer } = self.offer.take()?;
|
let SurfaceAndOffer { window_id, offer } = self.offer.take()?;
|
||||||
let pipe = Pipe::new()
|
let read = offer
|
||||||
.map_err(|err| log::error!("Unable to create pipe: {:#}", err))
|
.receive(URI_MIME_TYPE.to_string())
|
||||||
|
.map_err(|err| log::error!("Unable to receive data: {:#}", err))
|
||||||
.ok()?;
|
.ok()?;
|
||||||
offer.receive(URI_MIME_TYPE.to_string(), pipe.write.as_raw_fd());
|
|
||||||
let read = pipe.read;
|
|
||||||
offer.finish();
|
offer.finish();
|
||||||
Some(SurfaceAndPipe { window_id, read })
|
Some(SurfaceAndPipe { window_id, read })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn read_paths_from_pipe(read: FileDescriptor) -> Option<Vec<PathBuf>> {
|
pub(super) fn read_paths_from_pipe(read: ReadPipe) -> Option<Vec<PathBuf>> {
|
||||||
read_pipe_with_timeout(read)
|
read_pipe_with_timeout(read)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
log::error!("Error while reading pipe from drop result: {:#}", err);
|
log::error!("Error while reading pipe from drop result: {:#}", err);
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use smithay_client_toolkit::compositor::SurfaceData;
|
use smithay_client_toolkit::compositor::SurfaceData;
|
||||||
use smithay_client_toolkit::seat::pointer::{
|
use smithay_client_toolkit::seat::pointer::{
|
||||||
PointerData, PointerDataExt, PointerEvent, PointerEventKind, PointerHandler,
|
PointerData, PointerDataExt, PointerEvent, PointerEventKind, PointerHandler,
|
||||||
};
|
};
|
||||||
use smithay_client_toolkit::shell::xdg::frame::{DecorationsFrame, FrameClick};
|
|
||||||
use wayland_client::backend::ObjectId;
|
use wayland_client::backend::ObjectId;
|
||||||
use wayland_client::protocol::wl_pointer::{ButtonState, WlPointer};
|
use wayland_client::protocol::wl_pointer::{ButtonState, WlPointer};
|
||||||
use wayland_client::protocol::wl_seat::WlSeat;
|
use wayland_client::protocol::wl_seat::WlSeat;
|
||||||
use wayland_client::{Connection, Proxy, QueueHandle};
|
use wayland_client::{Connection, Proxy, QueueHandle};
|
||||||
|
use wayland_csd_frame::{DecorationsFrame, FrameClick};
|
||||||
use wezterm_input_types::MousePress;
|
use wezterm_input_types::MousePress;
|
||||||
|
|
||||||
use crate::wayland::SurfaceUserData;
|
use crate::wayland::SurfaceUserData;
|
||||||
@ -221,16 +222,31 @@ impl WaylandState {
|
|||||||
if let Some(frame) = inner.decorations.as_mut() {
|
if let Some(frame) = inner.decorations.as_mut() {
|
||||||
match evt.kind {
|
match evt.kind {
|
||||||
PointerEventKind::Enter { .. } => {
|
PointerEventKind::Enter { .. } => {
|
||||||
frame.click_point_moved(&evt.surface, x, y);
|
frame.click_point_moved(Duration::ZERO, &evt.surface.id(), x, y);
|
||||||
}
|
}
|
||||||
PointerEventKind::Leave { .. } => {
|
PointerEventKind::Leave { .. } => {
|
||||||
frame.click_point_left();
|
frame.click_point_left();
|
||||||
}
|
}
|
||||||
PointerEventKind::Motion { .. } => {
|
PointerEventKind::Motion { time, .. } => {
|
||||||
frame.click_point_moved(&evt.surface, x, y);
|
frame.click_point_moved(
|
||||||
|
Duration::from_millis(time as u64),
|
||||||
|
&evt.surface.id(),
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
PointerEventKind::Press { button, serial, .. }
|
PointerEventKind::Press {
|
||||||
| PointerEventKind::Release { button, serial, .. } => {
|
button,
|
||||||
|
serial,
|
||||||
|
time,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| PointerEventKind::Release {
|
||||||
|
button,
|
||||||
|
serial,
|
||||||
|
time,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
let pressed = if matches!(evt.kind, PointerEventKind::Press { .. }) {
|
let pressed = if matches!(evt.kind, PointerEventKind::Press { .. }) {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@ -241,7 +257,9 @@ impl WaylandState {
|
|||||||
0x111 => FrameClick::Alternate,
|
0x111 => FrameClick::Alternate,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
if let Some(action) = frame.on_click(click, pressed) {
|
if let Some(action) =
|
||||||
|
frame.on_click(Duration::from_millis(time as u64), click, pressed)
|
||||||
|
{
|
||||||
inner.frame_action(pointer, serial, action);
|
inner.frame_action(pointer, serial, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
use smithay_client_toolkit::compositor::SurfaceData;
|
||||||
use smithay_client_toolkit::seat::pointer::ThemeSpec;
|
use smithay_client_toolkit::seat::pointer::ThemeSpec;
|
||||||
use smithay_client_toolkit::seat::{Capability, SeatHandler, SeatState};
|
use smithay_client_toolkit::seat::{Capability, SeatHandler, SeatState};
|
||||||
use wayland_client::protocol::wl_seat::WlSeat;
|
use wayland_client::protocol::wl_seat::WlSeat;
|
||||||
use wayland_client::{Connection, QueueHandle};
|
use wayland_client::{Connection, QueueHandle};
|
||||||
|
|
||||||
use crate::wayland::copy_and_paste::PrimarySelectionManagerData;
|
|
||||||
use crate::wayland::keyboard::KeyboardData;
|
use crate::wayland::keyboard::KeyboardData;
|
||||||
use crate::wayland::pointer::PointerUserData;
|
use crate::wayland::pointer::PointerUserData;
|
||||||
|
|
||||||
@ -14,9 +14,7 @@ impl SeatHandler for WaylandState {
|
|||||||
&mut self.seat
|
&mut self.seat
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_seat(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _seat: WlSeat) {
|
fn new_seat(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _seat: WlSeat) {}
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_capability(
|
fn new_capability(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -26,7 +24,10 @@ impl SeatHandler for WaylandState {
|
|||||||
capability: smithay_client_toolkit::seat::Capability,
|
capability: smithay_client_toolkit::seat::Capability,
|
||||||
) {
|
) {
|
||||||
if capability == Capability::Keyboard && self.keyboard.is_none() {
|
if capability == Capability::Keyboard && self.keyboard.is_none() {
|
||||||
log::trace!("Setting keyboard capability");
|
log::trace!(
|
||||||
|
"Setting keyboard
|
||||||
|
capability"
|
||||||
|
);
|
||||||
let keyboard = seat.get_keyboard(qh, KeyboardData {});
|
let keyboard = seat.get_keyboard(qh, KeyboardData {});
|
||||||
self.keyboard = Some(keyboard.clone());
|
self.keyboard = Some(keyboard.clone());
|
||||||
|
|
||||||
@ -36,12 +37,18 @@ impl SeatHandler for WaylandState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if capability == Capability::Pointer && self.pointer.is_none() {
|
if capability == Capability::Pointer && self.pointer.is_none() {
|
||||||
log::trace!("Setting pointer capability");
|
log::trace!(
|
||||||
|
"Setting
|
||||||
|
pointer capability"
|
||||||
|
);
|
||||||
|
let surface = self.compositor.create_surface(qh);
|
||||||
let pointer = self
|
let pointer = self
|
||||||
.seat
|
.seat
|
||||||
.get_pointer_with_theme_and_data(
|
.get_pointer_with_theme_and_data::<WaylandState, SurfaceData, PointerUserData>(
|
||||||
qh,
|
qh,
|
||||||
&seat,
|
&seat,
|
||||||
|
self.shm.wl_shm(),
|
||||||
|
surface,
|
||||||
ThemeSpec::System,
|
ThemeSpec::System,
|
||||||
PointerUserData::new(seat.clone()),
|
PointerUserData::new(seat.clone()),
|
||||||
)
|
)
|
||||||
@ -52,11 +59,11 @@ impl SeatHandler for WaylandState {
|
|||||||
let data_device = data_device_manager.get_data_device(qh, &seat);
|
let data_device = data_device_manager.get_data_device(qh, &seat);
|
||||||
self.data_device.replace(data_device);
|
self.data_device.replace(data_device);
|
||||||
|
|
||||||
let primary_select_device = self.primary_selection_manager.as_ref().map(|m| {
|
let primary_select_device = self
|
||||||
m.manager
|
.primary_selection_manager
|
||||||
.get_device(&seat, qh, PrimarySelectionManagerData::default())
|
.as_ref()
|
||||||
});
|
.map(|m| m.get_selection_device(qh, &seat));
|
||||||
self.primary_select_device = primary_select_device;
|
self.primary_selection_device = primary_select_device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,10 +74,9 @@ impl SeatHandler for WaylandState {
|
|||||||
_seat: WlSeat,
|
_seat: WlSeat,
|
||||||
_capability: smithay_client_toolkit::seat::Capability,
|
_capability: smithay_client_toolkit::seat::Capability,
|
||||||
) {
|
) {
|
||||||
|
// we need to clean up the keyboard and pointer resources we created earlier
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_seat(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _seat: WlSeat) {
|
fn remove_seat(&mut self, _conn: &Connection, _qh: &QueueHandle<Self>, _seat: WlSeat) {}
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use smithay_client_toolkit::compositor::CompositorState;
|
use smithay_client_toolkit::compositor::{CompositorState, SurfaceData};
|
||||||
use smithay_client_toolkit::data_device_manager::data_device::DataDevice;
|
use smithay_client_toolkit::data_device_manager::data_device::DataDevice;
|
||||||
use smithay_client_toolkit::data_device_manager::data_source::CopyPasteSource;
|
use smithay_client_toolkit::data_device_manager::data_source::CopyPasteSource;
|
||||||
use smithay_client_toolkit::data_device_manager::DataDeviceManagerState;
|
use smithay_client_toolkit::data_device_manager::DataDeviceManagerState;
|
||||||
@ -13,6 +13,9 @@ use smithay_client_toolkit::reexports::protocols_wlr::output_management::v1::cli
|
|||||||
use smithay_client_toolkit::reexports::protocols_wlr::output_management::v1::client::zwlr_output_manager_v1::ZwlrOutputManagerV1;
|
use smithay_client_toolkit::reexports::protocols_wlr::output_management::v1::client::zwlr_output_manager_v1::ZwlrOutputManagerV1;
|
||||||
use smithay_client_toolkit::reexports::protocols_wlr::output_management::v1::client::zwlr_output_mode_v1::ZwlrOutputModeV1;
|
use smithay_client_toolkit::reexports::protocols_wlr::output_management::v1::client::zwlr_output_mode_v1::ZwlrOutputModeV1;
|
||||||
use smithay_client_toolkit::registry::{ProvidesRegistryState, RegistryState};
|
use smithay_client_toolkit::registry::{ProvidesRegistryState, RegistryState};
|
||||||
|
use smithay_client_toolkit::primary_selection::PrimarySelectionManagerState;
|
||||||
|
use smithay_client_toolkit::primary_selection::selection::PrimarySelectionSource;
|
||||||
|
use smithay_client_toolkit::primary_selection::device::PrimarySelectionDevice;
|
||||||
use smithay_client_toolkit::seat::pointer::ThemedPointer;
|
use smithay_client_toolkit::seat::pointer::ThemedPointer;
|
||||||
use smithay_client_toolkit::seat::SeatState;
|
use smithay_client_toolkit::seat::SeatState;
|
||||||
use smithay_client_toolkit::shell::xdg::XdgShell;
|
use smithay_client_toolkit::shell::xdg::XdgShell;
|
||||||
@ -20,25 +23,18 @@ use smithay_client_toolkit::shm::slot::SlotPool;
|
|||||||
use smithay_client_toolkit::shm::{Shm, ShmHandler};
|
use smithay_client_toolkit::shm::{Shm, ShmHandler};
|
||||||
use smithay_client_toolkit::subcompositor::SubcompositorState;
|
use smithay_client_toolkit::subcompositor::SubcompositorState;
|
||||||
use smithay_client_toolkit::{
|
use smithay_client_toolkit::{
|
||||||
delegate_compositor, delegate_data_device, delegate_data_device_manager, delegate_data_offer, delegate_data_source, delegate_output, delegate_registry, delegate_seat, delegate_shm, delegate_subcompositor, delegate_xdg_shell, delegate_xdg_window, registry_handlers
|
delegate_compositor, delegate_pointer, delegate_data_device, delegate_primary_selection, delegate_output, delegate_registry, delegate_seat, delegate_shm, delegate_subcompositor, delegate_xdg_shell, delegate_xdg_window, registry_handlers
|
||||||
};
|
};
|
||||||
use wayland_client::backend::ObjectId;
|
use wayland_client::backend::ObjectId;
|
||||||
use wayland_client::globals::GlobalList;
|
use wayland_client::globals::GlobalList;
|
||||||
use wayland_client::protocol::wl_keyboard::WlKeyboard;
|
use wayland_client::protocol::wl_keyboard::WlKeyboard;
|
||||||
use wayland_client::protocol::wl_output::WlOutput;
|
use wayland_client::protocol::wl_output::WlOutput;
|
||||||
use wayland_client::protocol::wl_pointer::WlPointer;
|
|
||||||
use wayland_client::protocol::wl_surface::WlSurface;
|
|
||||||
use wayland_client::{delegate_dispatch, Connection, QueueHandle};
|
use wayland_client::{delegate_dispatch, Connection, QueueHandle};
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_device_manager_v1::ZwpPrimarySelectionDeviceManagerV1;
|
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_device_v1::ZwpPrimarySelectionDeviceV1;
|
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_offer_v1::ZwpPrimarySelectionOfferV1;
|
|
||||||
use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_source_v1::ZwpPrimarySelectionSourceV1;
|
|
||||||
use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_manager_v3::ZwpTextInputManagerV3;
|
use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_manager_v3::ZwpTextInputManagerV3;
|
||||||
use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_v3::ZwpTextInputV3;
|
use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_v3::ZwpTextInputV3;
|
||||||
|
|
||||||
use crate::x11::KeyboardWithFallback;
|
use crate::x11::KeyboardWithFallback;
|
||||||
|
|
||||||
use super::copy_and_paste::{PrimarySelectionManagerData, PrimarySelectionManagerState};
|
|
||||||
use super::inputhandler::{TextInputData, TextInputState};
|
use super::inputhandler::{TextInputData, TextInputState};
|
||||||
use super::pointer::{PendingMouse, PointerUserData};
|
use super::pointer::{PendingMouse, PointerUserData};
|
||||||
use super::{OutputManagerData, OutputManagerState, SurfaceUserData, WaylandWindowInner};
|
use super::{OutputManagerData, OutputManagerState, SurfaceUserData, WaylandWindowInner};
|
||||||
@ -71,8 +67,8 @@ pub(super) struct WaylandState {
|
|||||||
pub(super) data_device: Option<DataDevice>,
|
pub(super) data_device: Option<DataDevice>,
|
||||||
pub(super) copy_paste_source: Option<(CopyPasteSource, String)>,
|
pub(super) copy_paste_source: Option<(CopyPasteSource, String)>,
|
||||||
pub(super) primary_selection_manager: Option<PrimarySelectionManagerState>,
|
pub(super) primary_selection_manager: Option<PrimarySelectionManagerState>,
|
||||||
pub(super) primary_select_device: Option<ZwpPrimarySelectionDeviceV1>,
|
pub(super) primary_selection_source: Option<(PrimarySelectionSource, String)>,
|
||||||
pub(super) primary_selection_source: Option<(ZwpPrimarySelectionSourceV1, String)>,
|
pub(super) primary_selection_device: Option<PrimarySelectionDevice>,
|
||||||
pub(super) shm: Shm,
|
pub(super) shm: Shm,
|
||||||
pub(super) mem_pool: RefCell<SlotPool>,
|
pub(super) mem_pool: RefCell<SlotPool>,
|
||||||
}
|
}
|
||||||
@ -113,8 +109,8 @@ impl WaylandState {
|
|||||||
data_device: None,
|
data_device: None,
|
||||||
copy_paste_source: None,
|
copy_paste_source: None,
|
||||||
primary_selection_manager: PrimarySelectionManagerState::bind(globals, qh).ok(),
|
primary_selection_manager: PrimarySelectionManagerState::bind(globals, qh).ok(),
|
||||||
primary_select_device: None,
|
|
||||||
primary_selection_source: None,
|
primary_selection_source: None,
|
||||||
|
primary_selection_device: None,
|
||||||
shm,
|
shm,
|
||||||
mem_pool: RefCell::new(mem_pool),
|
mem_pool: RefCell::new(mem_pool),
|
||||||
};
|
};
|
||||||
@ -153,28 +149,20 @@ impl OutputHandler for WaylandState {
|
|||||||
log::trace!("output destroyed: OutputHandler");
|
log::trace!("output destroyed: OutputHandler");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Undocumented in sctk 0.17: This is required to use have user data with a surface
|
|
||||||
// Will be just delegate_compositor!(WaylandState, surface: [SurfaceData, SurfaceUserData]) in 0.18
|
|
||||||
delegate_dispatch!(WaylandState: [ WlSurface: SurfaceUserData] => CompositorState);
|
|
||||||
|
|
||||||
delegate_registry!(WaylandState);
|
delegate_registry!(WaylandState);
|
||||||
|
|
||||||
delegate_shm!(WaylandState);
|
delegate_shm!(WaylandState);
|
||||||
|
|
||||||
delegate_output!(WaylandState);
|
delegate_output!(WaylandState);
|
||||||
delegate_compositor!(WaylandState);
|
delegate_compositor!(WaylandState, surface: [SurfaceData, SurfaceUserData]);
|
||||||
delegate_subcompositor!(WaylandState);
|
delegate_subcompositor!(WaylandState);
|
||||||
|
|
||||||
delegate_seat!(WaylandState);
|
delegate_seat!(WaylandState);
|
||||||
|
|
||||||
delegate_data_device_manager!(WaylandState);
|
|
||||||
delegate_data_device!(WaylandState);
|
delegate_data_device!(WaylandState);
|
||||||
delegate_data_source!(WaylandState);
|
delegate_primary_selection!(WaylandState);
|
||||||
delegate_data_offer!(WaylandState);
|
delegate_pointer!(WaylandState, pointer: [PointerUserData]);
|
||||||
|
|
||||||
// Updating to 0.18 should have this be able to work
|
|
||||||
// delegate_pointer!(WaylandState, pointer: [PointerUserData]);
|
|
||||||
delegate_dispatch!(WaylandState: [WlPointer: PointerUserData] => SeatState);
|
|
||||||
|
|
||||||
delegate_xdg_shell!(WaylandState);
|
delegate_xdg_shell!(WaylandState);
|
||||||
delegate_xdg_window!(WaylandState);
|
delegate_xdg_window!(WaylandState);
|
||||||
@ -185,8 +173,3 @@ delegate_dispatch!(WaylandState: [ZwpTextInputV3: TextInputData] => TextInputSta
|
|||||||
delegate_dispatch!(WaylandState: [ZwlrOutputManagerV1: GlobalData] => OutputManagerState);
|
delegate_dispatch!(WaylandState: [ZwlrOutputManagerV1: GlobalData] => OutputManagerState);
|
||||||
delegate_dispatch!(WaylandState: [ZwlrOutputHeadV1: OutputManagerData] => OutputManagerState);
|
delegate_dispatch!(WaylandState: [ZwlrOutputHeadV1: OutputManagerData] => OutputManagerState);
|
||||||
delegate_dispatch!(WaylandState: [ZwlrOutputModeV1: OutputManagerData] => OutputManagerState);
|
delegate_dispatch!(WaylandState: [ZwlrOutputModeV1: OutputManagerData] => OutputManagerState);
|
||||||
|
|
||||||
delegate_dispatch!(WaylandState: [ZwpPrimarySelectionDeviceManagerV1: GlobalData] => PrimarySelectionManagerState);
|
|
||||||
delegate_dispatch!(WaylandState: [ZwpPrimarySelectionDeviceV1: PrimarySelectionManagerData] => PrimarySelectionManagerState);
|
|
||||||
delegate_dispatch!(WaylandState: [ZwpPrimarySelectionSourceV1: PrimarySelectionManagerData] => PrimarySelectionManagerState);
|
|
||||||
delegate_dispatch!(WaylandState: [ZwpPrimarySelectionOfferV1: PrimarySelectionManagerData] => PrimarySelectionManagerState);
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::RefCell;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@ -14,18 +14,18 @@ use anyhow::{anyhow, bail};
|
|||||||
use async_io::Timer;
|
use async_io::Timer;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use config::ConfigHandle;
|
use config::ConfigHandle;
|
||||||
use filedescriptor::FileDescriptor;
|
|
||||||
use promise::{Future, Promise};
|
use promise::{Future, Promise};
|
||||||
use raw_window_handle::{
|
use raw_window_handle::{
|
||||||
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||||
WaylandDisplayHandle, WaylandWindowHandle,
|
WaylandDisplayHandle, WaylandWindowHandle,
|
||||||
};
|
};
|
||||||
use smithay_client_toolkit::compositor::{CompositorHandler, SurfaceData, SurfaceDataExt};
|
use smithay_client_toolkit::compositor::{CompositorHandler, SurfaceData, SurfaceDataExt};
|
||||||
use smithay_client_toolkit::shell::xdg::frame::fallback_frame::FallbackFrame;
|
use smithay_client_toolkit::data_device_manager::ReadPipe;
|
||||||
use smithay_client_toolkit::shell::xdg::frame::{DecorationsFrame, FrameAction};
|
use smithay_client_toolkit::seat::pointer::CursorIcon;
|
||||||
|
use smithay_client_toolkit::shell::xdg::fallback_frame::FallbackFrame;
|
||||||
use smithay_client_toolkit::shell::xdg::window::{
|
use smithay_client_toolkit::shell::xdg::window::{
|
||||||
DecorationMode, Window as XdgWindow, WindowConfigure, WindowDecorations as Decorations,
|
DecorationMode, Window as XdgWindow, WindowConfigure, WindowDecorations as Decorations,
|
||||||
WindowHandler, WindowState as SCTKWindowState,
|
WindowHandler,
|
||||||
};
|
};
|
||||||
use smithay_client_toolkit::shell::xdg::XdgSurface;
|
use smithay_client_toolkit::shell::xdg::XdgSurface;
|
||||||
use smithay_client_toolkit::shell::WaylandSurface;
|
use smithay_client_toolkit::shell::WaylandSurface;
|
||||||
@ -34,7 +34,9 @@ use wayland_client::protocol::wl_keyboard::{Event as WlKeyboardEvent, KeyState};
|
|||||||
use wayland_client::protocol::wl_pointer::{ButtonState, WlPointer};
|
use wayland_client::protocol::wl_pointer::{ButtonState, WlPointer};
|
||||||
use wayland_client::protocol::wl_surface::WlSurface;
|
use wayland_client::protocol::wl_surface::WlSurface;
|
||||||
use wayland_client::{Connection as WConnection, Proxy};
|
use wayland_client::{Connection as WConnection, Proxy};
|
||||||
|
use wayland_csd_frame::{DecorationsFrame, FrameAction, WindowState as CsdWindowState};
|
||||||
use wayland_egl::{is_available as egl_is_available, WlEglSurface};
|
use wayland_egl::{is_available as egl_is_available, WlEglSurface};
|
||||||
|
use wayland_protocols::xdg::shell::client::xdg_toplevel;
|
||||||
use wezterm_font::FontConfiguration;
|
use wezterm_font::FontConfiguration;
|
||||||
use wezterm_input_types::{
|
use wezterm_input_types::{
|
||||||
KeyboardLedStatus, Modifiers, MouseButtons, MouseEvent, MouseEventKind, MousePress,
|
KeyboardLedStatus, Modifiers, MouseButtons, MouseEvent, MouseEventKind, MousePress,
|
||||||
@ -193,11 +195,6 @@ impl WaylandWindow {
|
|||||||
compositor.create_surface_with_data(&qh, surface_data)
|
compositor.create_surface_with_data(&qh, surface_data)
|
||||||
};
|
};
|
||||||
|
|
||||||
let pointer_surface = {
|
|
||||||
let compositor = &conn.wayland_state.borrow().compositor;
|
|
||||||
compositor.create_surface(&qh)
|
|
||||||
};
|
|
||||||
|
|
||||||
let ResolvedGeometry {
|
let ResolvedGeometry {
|
||||||
x: _,
|
x: _,
|
||||||
y: _,
|
y: _,
|
||||||
@ -269,7 +266,6 @@ impl WaylandWindow {
|
|||||||
key_repeat: None,
|
key_repeat: None,
|
||||||
pending_event,
|
pending_event,
|
||||||
pending_mouse,
|
pending_mouse,
|
||||||
pointer_surface,
|
|
||||||
|
|
||||||
pending_first_configure: Some(pending_first_configure),
|
pending_first_configure: Some(pending_first_configure),
|
||||||
frame_callback: None,
|
frame_callback: None,
|
||||||
@ -443,10 +439,10 @@ pub(crate) struct PendingEvent {
|
|||||||
pub(crate) window_state: Option<WindowState>,
|
pub(crate) window_state: Option<WindowState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_pipe_with_timeout(mut file: FileDescriptor) -> anyhow::Result<String> {
|
pub(crate) fn read_pipe_with_timeout(mut file: ReadPipe) -> anyhow::Result<String> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
|
|
||||||
file.set_non_blocking(true)?;
|
unsafe { libc::fcntl(file.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK) };
|
||||||
let mut pfd = libc::pollfd {
|
let mut pfd = libc::pollfd {
|
||||||
fd: file.as_raw_fd(),
|
fd: file.as_raw_fd(),
|
||||||
events: libc::POLLIN,
|
events: libc::POLLIN,
|
||||||
@ -483,7 +479,6 @@ pub struct WaylandWindowInner {
|
|||||||
dimensions: Dimensions,
|
dimensions: Dimensions,
|
||||||
resize_increments: Option<ResizeIncrement>,
|
resize_increments: Option<ResizeIncrement>,
|
||||||
window_state: WindowState,
|
window_state: WindowState,
|
||||||
pointer_surface: WlSurface,
|
|
||||||
last_mouse_coords: Point,
|
last_mouse_coords: Point,
|
||||||
mouse_buttons: MouseButtons,
|
mouse_buttons: MouseButtons,
|
||||||
hscroll_remainder: f64,
|
hscroll_remainder: f64,
|
||||||
@ -928,27 +923,20 @@ impl WaylandWindowInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor(&mut self, cursor: Option<MouseCursor>) {
|
fn set_cursor(&mut self, cursor: Option<MouseCursor>) {
|
||||||
let name = cursor.map_or("none", |cursor| match cursor {
|
let icon = cursor.map_or(CursorIcon::Default, |cursor| match cursor {
|
||||||
MouseCursor::Arrow => "arrow",
|
MouseCursor::Arrow => CursorIcon::Default,
|
||||||
MouseCursor::Hand => "hand",
|
MouseCursor::Hand => CursorIcon::Pointer,
|
||||||
MouseCursor::SizeUpDown => "ns-resize",
|
MouseCursor::SizeUpDown => CursorIcon::NsResize,
|
||||||
MouseCursor::SizeLeftRight => "ew-resize",
|
MouseCursor::SizeLeftRight => CursorIcon::EwResize,
|
||||||
MouseCursor::Text => "xterm",
|
MouseCursor::Text => CursorIcon::Text,
|
||||||
});
|
});
|
||||||
let conn = Connection::get().unwrap().wayland();
|
let conn = Connection::get().unwrap().wayland();
|
||||||
let state = conn.wayland_state.borrow_mut();
|
let mut state = conn.wayland_state.borrow_mut();
|
||||||
let (shm, pointer) =
|
let pointer = state.pointer.as_mut().unwrap();
|
||||||
RefMut::map_split(state, |s| (&mut s.shm, s.pointer.as_mut().unwrap()));
|
|
||||||
|
|
||||||
// Much different API in 0.18
|
// Much different API in 0.18
|
||||||
if let Err(err) = pointer.set_cursor(
|
if let Err(err) = pointer.set_cursor(&conn.connection, icon) {
|
||||||
&conn.connection,
|
log::error!("set_cursor: (icon={}) {}", icon, err);
|
||||||
name,
|
|
||||||
shm.wl_shm(),
|
|
||||||
&self.pointer_surface,
|
|
||||||
1,
|
|
||||||
) {
|
|
||||||
log::error!("set_cursor: {}", err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1182,8 +1170,14 @@ impl WaylandWindowInner {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.show_window_menu(seat, serial, (x, y))
|
.show_window_menu(seat, serial, (x, y))
|
||||||
}
|
}
|
||||||
FrameAction::Resize(edge) => self.window.as_ref().unwrap().resize(seat, serial, edge),
|
FrameAction::Resize(edge) => {
|
||||||
|
self.window
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.resize(seat, serial, frame_edge_to_window_edge(edge))
|
||||||
|
}
|
||||||
FrameAction::Move => self.window.as_ref().unwrap().move_(seat, serial),
|
FrameAction::Move => self.window.as_ref().unwrap().move_(seat, serial),
|
||||||
|
_ => {} // just ignore unrecognized frame actions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1230,14 +1224,14 @@ impl WaylandState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut state = WindowState::default();
|
let mut state = WindowState::default();
|
||||||
if configure.state.contains(SCTKWindowState::FULLSCREEN) {
|
if configure.state.contains(CsdWindowState::FULLSCREEN) {
|
||||||
state |= WindowState::FULL_SCREEN;
|
state |= WindowState::FULL_SCREEN;
|
||||||
}
|
}
|
||||||
let fs_bits = SCTKWindowState::MAXIMIZED
|
let fs_bits = CsdWindowState::MAXIMIZED
|
||||||
| SCTKWindowState::TILED_LEFT
|
| CsdWindowState::TILED_LEFT
|
||||||
| SCTKWindowState::TILED_RIGHT
|
| CsdWindowState::TILED_RIGHT
|
||||||
| SCTKWindowState::TILED_TOP
|
| CsdWindowState::TILED_TOP
|
||||||
| SCTKWindowState::TILED_BOTTOM;
|
| CsdWindowState::TILED_BOTTOM;
|
||||||
if !((configure.state & fs_bits).is_empty()) {
|
if !((configure.state & fs_bits).is_empty()) {
|
||||||
state |= WindowState::MAXIMIZED;
|
state |= WindowState::MAXIMIZED;
|
||||||
}
|
}
|
||||||
@ -1275,20 +1269,29 @@ impl CompositorHandler for WaylandState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_conn: &WConnection,
|
_conn: &WConnection,
|
||||||
_qh: &wayland_client::QueueHandle<Self>,
|
_qh: &wayland_client::QueueHandle<Self>,
|
||||||
_surface: &wayland_client::protocol::wl_surface::WlSurface,
|
surface: &wayland_client::protocol::wl_surface::WlSurface,
|
||||||
_new_factor: i32,
|
new_factor: i32,
|
||||||
) {
|
) {
|
||||||
// TODO: uncomment after upgrading SCTK to 0.18
|
let window_id = SurfaceUserData::from_wl(surface).window_id;
|
||||||
// let window_id = SurfaceUserData::from_wl(surface).window_id;
|
WaylandConnection::with_window_inner(window_id, move |inner| {
|
||||||
// WaylandConnection::with_window_inner(window_id, |inner| {
|
if let Some(frame) = inner.decorations.as_mut() {
|
||||||
// if let Some(frame) = inner.window_frame.as_mut() {
|
frame.set_scaling_factor(new_factor as f64);
|
||||||
// frame.set_scaling_factor(new_factor as f64);
|
}
|
||||||
// }
|
Ok(())
|
||||||
// Ok(())
|
});
|
||||||
// });
|
|
||||||
// We do nothing, we get the scale_factor from surface_data
|
// We do nothing, we get the scale_factor from surface_data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn transform_changed(
|
||||||
|
&mut self,
|
||||||
|
_conn: &WConnection,
|
||||||
|
_qh: &wayland_client::QueueHandle<Self>,
|
||||||
|
_surface: &wayland_client::protocol::wl_surface::WlSurface,
|
||||||
|
_new_transform: wayland_client::protocol::wl_output::Transform,
|
||||||
|
) {
|
||||||
|
// Nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
fn frame(
|
fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
_conn: &WConnection,
|
_conn: &WConnection,
|
||||||
@ -1354,7 +1357,7 @@ unsafe impl HasRawWindowHandle for WaylandWindowInner {
|
|||||||
fn raw_window_handle(&self) -> RawWindowHandle {
|
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||||
let mut handle = WaylandWindowHandle::empty();
|
let mut handle = WaylandWindowHandle::empty();
|
||||||
let surface = self.surface();
|
let surface = self.surface();
|
||||||
handle.surface = surface.id().as_ptr() as *mut _;
|
handle.surface = surface.id().interface().c_ptr.unwrap() as *const _ as *mut _;
|
||||||
RawWindowHandle::Wayland(handle)
|
RawWindowHandle::Wayland(handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1363,7 +1366,13 @@ unsafe impl HasRawDisplayHandle for WaylandWindow {
|
|||||||
fn raw_display_handle(&self) -> RawDisplayHandle {
|
fn raw_display_handle(&self) -> RawDisplayHandle {
|
||||||
let mut handle = WaylandDisplayHandle::empty();
|
let mut handle = WaylandDisplayHandle::empty();
|
||||||
let conn = WaylandConnection::get().unwrap().wayland();
|
let conn = WaylandConnection::get().unwrap().wayland();
|
||||||
handle.display = conn.connection.backend().display_ptr() as *mut _;
|
handle.display = conn
|
||||||
|
.connection
|
||||||
|
.backend()
|
||||||
|
.display_id()
|
||||||
|
.interface()
|
||||||
|
.c_ptr
|
||||||
|
.unwrap() as *const _ as *mut _;
|
||||||
RawDisplayHandle::Wayland(handle)
|
RawDisplayHandle::Wayland(handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1380,3 +1389,22 @@ unsafe impl HasRawWindowHandle for WaylandWindow {
|
|||||||
inner.raw_window_handle()
|
inner.raw_window_handle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn frame_edge_to_window_edge(
|
||||||
|
frame_edge: wayland_csd_frame::ResizeEdge,
|
||||||
|
) -> xdg_toplevel::ResizeEdge {
|
||||||
|
use wayland_csd_frame::ResizeEdge;
|
||||||
|
use xdg_toplevel::ResizeEdge as XdgResizeEdge;
|
||||||
|
match frame_edge {
|
||||||
|
ResizeEdge::None => XdgResizeEdge::None,
|
||||||
|
ResizeEdge::Top => XdgResizeEdge::Top,
|
||||||
|
ResizeEdge::Bottom => XdgResizeEdge::Bottom,
|
||||||
|
ResizeEdge::Left => XdgResizeEdge::Left,
|
||||||
|
ResizeEdge::TopLeft => XdgResizeEdge::TopLeft,
|
||||||
|
ResizeEdge::BottomLeft => XdgResizeEdge::BottomLeft,
|
||||||
|
ResizeEdge::Right => XdgResizeEdge::Right,
|
||||||
|
ResizeEdge::TopRight => XdgResizeEdge::TopRight,
|
||||||
|
ResizeEdge::BottomRight => XdgResizeEdge::BottomRight,
|
||||||
|
_ => XdgResizeEdge::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user