-
-
Notifications
You must be signed in to change notification settings - Fork 264
Attach dialog to window #384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ use std::{ | |
| collections::{HashMap, HashSet, VecDeque}, | ||
| fmt::Display, | ||
| mem::swap, | ||
| sync::{Arc, Mutex}, | ||
| task::{Poll, ready}, | ||
| }; | ||
|
|
||
|
|
@@ -129,6 +130,24 @@ pub struct InputCapture { | |
| pending: VecDeque<(CaptureHandle, CaptureEvent)>, | ||
| } | ||
|
|
||
| #[derive(Clone, Debug)] | ||
| pub enum WindowIdentifier { | ||
| Wayland(String), | ||
| X11(u32), | ||
| } | ||
|
|
||
| #[cfg(all(unix, feature = "libei"))] | ||
| impl Into<ashpd::WindowIdentifier> for WindowIdentifier { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then this impl can go into ashpd itself |
||
| fn into(self) -> ashpd::WindowIdentifier { | ||
| match self { | ||
| WindowIdentifier::Wayland(handle) => { | ||
| ashpd::WindowIdentifier::from_xdg_foreign_exported(handle) | ||
| } | ||
| WindowIdentifier::X11(_) => todo!(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl InputCapture { | ||
| /// create a new client with the given id | ||
| pub async fn create(&mut self, id: CaptureHandle, pos: Position) -> Result<(), CaptureError> { | ||
|
|
@@ -190,8 +209,11 @@ impl InputCapture { | |
| } | ||
|
|
||
| /// creates a new [`InputCapture`] | ||
| pub async fn new(backend: Option<Backend>) -> Result<Self, CaptureCreationError> { | ||
| let capture = create(backend).await?; | ||
| pub async fn new( | ||
| backend: Option<Backend>, | ||
| window_identifier: Arc<Mutex<Option<WindowIdentifier>>>, | ||
| ) -> Result<Self, CaptureCreationError> { | ||
| let capture = create(backend, window_identifier).await?; | ||
| Ok(Self { | ||
| capture, | ||
| id_map: Default::default(), | ||
|
|
@@ -293,13 +315,16 @@ trait Capture: Stream<Item = Result<(Position, CaptureEvent), CaptureError>> + U | |
|
|
||
| async fn create_backend( | ||
| backend: Backend, | ||
| window_identifier: Arc<Mutex<Option<WindowIdentifier>>>, | ||
| ) -> Result< | ||
| Box<dyn Capture<Item = Result<(Position, CaptureEvent), CaptureError>>>, | ||
| CaptureCreationError, | ||
| > { | ||
| match backend { | ||
| #[cfg(all(unix, feature = "libei", not(target_os = "macos")))] | ||
| Backend::InputCapturePortal => Ok(Box::new(libei::LibeiInputCapture::new().await?)), | ||
| Backend::InputCapturePortal => Ok(Box::new( | ||
| libei::LibeiInputCapture::new(window_identifier).await?, | ||
| )), | ||
| #[cfg(all(unix, feature = "layer_shell", not(target_os = "macos")))] | ||
| Backend::LayerShell => Ok(Box::new(layer_shell::LayerShellInputCapture::new()?)), | ||
| #[cfg(all(unix, feature = "x11", not(target_os = "macos")))] | ||
|
|
@@ -314,12 +339,13 @@ async fn create_backend( | |
|
|
||
| async fn create( | ||
| backend: Option<Backend>, | ||
| window_identifier: Arc<Mutex<Option<WindowIdentifier>>>, | ||
| ) -> Result< | ||
| Box<dyn Capture<Item = Result<(Position, CaptureEvent), CaptureError>>>, | ||
| CaptureCreationError, | ||
| > { | ||
| if let Some(backend) = backend { | ||
| let b = create_backend(backend).await; | ||
| let b = create_backend(backend, window_identifier).await; | ||
| if b.is_ok() { | ||
| log::info!("using capture backend: {backend}"); | ||
| } | ||
|
|
@@ -338,7 +364,7 @@ async fn create( | |
| #[cfg(target_os = "macos")] | ||
| Backend::MacOs, | ||
| ] { | ||
| match create_backend(backend).await { | ||
| match create_backend(backend, window_identifier.clone()).await { | ||
| Ok(b) => { | ||
| log::info!("using capture backend: {backend}"); | ||
| return Ok(b); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ use std::{env, process, str}; | |
|
|
||
| use window::Window; | ||
|
|
||
| use lan_mouse_ipc::FrontendEvent; | ||
| use lan_mouse_ipc::{FrontendEvent, FrontendRequest, WindowIdentifier}; | ||
|
|
||
| use adw::Application; | ||
| use gtk::{IconTheme, gdk::Display, glib::clone, prelude::*}; | ||
|
|
@@ -23,6 +23,9 @@ use gtk::{gio, glib, prelude::ApplicationExt}; | |
| use self::client_object::ClientObject; | ||
| use self::key_object::KeyObject; | ||
|
|
||
| #[cfg(all(unix, feature = "wayland_window_identifier", not(target_os = "macos")))] | ||
| use gdk4_wayland::WaylandToplevel; | ||
|
|
||
| use thiserror::Error; | ||
|
|
||
| #[derive(Error, Debug)] | ||
|
|
@@ -227,6 +230,28 @@ fn build_ui(app: &Application) { | |
| }); | ||
| } | ||
|
|
||
| // export TopLevel handle and send it to the service so that it can put the InpuCapture / RemoteDesktop | ||
| // windows on top of it using xdg-foreign. | ||
| #[cfg(all(unix, feature = "wayland_window_identifier", not(target_os = "macos")))] | ||
| window.connect_show(|window| { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have a gtk feature for this, why not make use of it?
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that possible? How do I get the handle from the GtkWindowIdentifier for serialization? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It implements Serialize/ToString but you will have to keep a ref to the ashpd type till the dialog is closed to not unexport the handle
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In that case I guess it would make sense to change bilelmoussaoui/ashpd#352 to take in the entire
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I should probably do that as well There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not if you make WindowIdentifierType public and you write a From trait impl for it. |
||
| // needs the surface so we have to present first! | ||
| if let Some(surface) = window.surface() { | ||
| if surface.display().backend().is_wayland() { | ||
| // let surface = surface.downcast::<WaylandSurface>(); | ||
| let toplevel = surface.downcast::<WaylandToplevel>().expect("xdg-toplevel"); | ||
| let window = window.clone(); | ||
| toplevel.export_handle(move |_toplevel, handle| { | ||
| if let Ok(handle) = handle { | ||
| let handle = handle.to_string(); | ||
| window.request(FrontendRequest::WindowIdentifier( | ||
| WindowIdentifier::Wayland(handle), | ||
| )); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| glib::spawn_future_local(clone!( | ||
| #[weak] | ||
| window, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a type similar to this in ashpd, named WindowIdentifierType. Maybe we can make it public, currently it is behind a backend feature