-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implements PlatformExt::set_modal for Wayland (#1237)
- Loading branch information
1 parent
c7fce0b
commit e4852da
Showing
12 changed files
with
201 additions
and
42 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use crate::rt::{block, Blocker, WinitWindow}; | ||
use std::ops::Deref; | ||
use wayland_protocols::xdg::dialog::v1::client::xdg_dialog_v1::XdgDialogV1; | ||
|
||
/// Encapsulates a modal window and its parent. | ||
/// | ||
/// This struct forces the modal window to be dropped before its parent. | ||
pub struct Modal<'a, W, P: WinitWindow> { | ||
window: W, | ||
wayland: Option<XdgDialogV1>, | ||
#[allow(dead_code)] | ||
blocker: Blocker<'a, P>, | ||
} | ||
|
||
impl<'a, W, P: WinitWindow> Modal<'a, W, P> { | ||
pub fn new(window: W, parent: &'a P, wayland: Option<XdgDialogV1>) -> Self { | ||
Self { | ||
window, | ||
wayland, | ||
blocker: block(parent), | ||
} | ||
} | ||
} | ||
|
||
impl<'a, W, P: WinitWindow> Drop for Modal<'a, W, P> { | ||
fn drop(&mut self) { | ||
if let Some(v) = self.wayland.take() { | ||
v.destroy(); | ||
} | ||
} | ||
} | ||
|
||
impl<'a, W, P: WinitWindow> Deref for Modal<'a, W, P> { | ||
type Target = W; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.window | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,48 @@ | ||
use super::PlatformError; | ||
use crate::rt::WinitWindow; | ||
use crate::ui::Wayland; | ||
use raw_window_handle::HasWindowHandle; | ||
|
||
pub fn set_modal( | ||
_: &Wayland, | ||
_: impl HasWindowHandle, | ||
_: impl HasWindowHandle, | ||
) -> Result<(), PlatformError> { | ||
// TODO: We need xdg_toplevel from the target window to use xdg_wm_dialog_v1::get_xdg_dialog. | ||
// AFAIK the only way to get it is using xdg_surface::get_toplevel. The problem is | ||
// xdg_wm_base::get_xdg_surface that return xdg_surface can be called only once per wl_surface | ||
// and this call already done by winit. So we need winit to expose either xdg_surface or | ||
// xdg_toplevel in order for us to implement this. | ||
Ok(()) | ||
use wayland_backend::sys::client::ObjectId; | ||
use wayland_client::Proxy; | ||
use wayland_protocols::xdg::dialog::v1::client::xdg_dialog_v1::XdgDialogV1; | ||
use wayland_protocols::xdg::shell::client::xdg_toplevel::XdgToplevel; | ||
|
||
/// # Safety | ||
/// `parent` must outlive `target`. | ||
pub unsafe fn set_modal( | ||
wayland: &Wayland, | ||
target: &impl WinitWindow, | ||
parent: &impl WinitWindow, | ||
) -> Result<XdgDialogV1, PlatformError> { | ||
// Get xdg_toplevel for parent. | ||
let mut queue = wayland.queue().borrow_mut(); | ||
let mut state = wayland.state().borrow_mut(); | ||
let qh = queue.handle(); | ||
let parent = get_xdg_toplevel(wayland, parent); | ||
|
||
// Get xdg_dialog_v1. | ||
let target = get_xdg_toplevel(wayland, target); | ||
let dialog = state.xdg_dialog().get_xdg_dialog(&target, &qh, ()); | ||
|
||
queue | ||
.roundtrip(&mut state) | ||
.map_err(PlatformError::CreateXdgDialogV1)?; | ||
|
||
// Set modal. | ||
target.set_parent(Some(&parent)); | ||
dialog.set_modal(); | ||
|
||
queue | ||
.roundtrip(&mut state) | ||
.map_err(PlatformError::SetModal)?; | ||
|
||
Ok(dialog) | ||
} | ||
|
||
/// # Safety | ||
/// `win` must outlive the returned [`XdgToplevel`]. | ||
unsafe fn get_xdg_toplevel(wayland: &Wayland, win: &impl WinitWindow) -> XdgToplevel { | ||
let obj = win.xdg_toplevel(); | ||
let obj = ObjectId::from_ptr(XdgToplevel::interface(), obj.cast()).unwrap(); | ||
|
||
XdgToplevel::from_id(wayland.connection(), obj).unwrap() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.