Skip to content

Commit

Permalink
Makes open_file and open_dir fallible
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon committed Feb 8, 2025
1 parent dfea04a commit 1bf9eae
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 73 deletions.
18 changes: 14 additions & 4 deletions gui/src/setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,13 @@ async fn get_dumper(win: SetupWizard) {
async fn browse_data_root(win: SetupWizard) {
// Ask the user to browse for a directory.
let path = match open_dir(&win, "Data location").await {
Some(v) => v,
None => return,
Ok(Some(v)) => v,
Ok(None) => return,
Err(e) => {
let m = slint::format!("Failed to browse for data location: {}.", e.display());
error(Some(&win), m).await;
return;
}
};

// Allow only valid unicode path.
Expand Down Expand Up @@ -196,8 +201,13 @@ async fn set_data_root(win: SetupWizard) {
async fn browse_firmware(win: SetupWizard) {
// Ask the user to browse for a file.
let path = match open_file(&win, "Select a firmware dump", FileType::Firmware).await {
Some(v) => v,
None => return,
Ok(Some(v)) => v,
Ok(None) => return,
Err(e) => {
let m = slint::format!("Failed to browse for a firmware dump: {}.", e.display());
error(Some(&win), m).await;
return;
}
};

// Allow only valid unicode path.
Expand Down
14 changes: 5 additions & 9 deletions gui/src/ui/backend/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[cfg(target_os = "linux")]
pub(super) use self::wayland::*;
pub(super) use self::window::Window;
pub(super) use self::window::*;

use i_slint_core::graphics::RequestedGraphicsAPI;
use i_slint_renderer_skia::SkiaRenderer;
Expand All @@ -25,7 +25,7 @@ use winit::window::WindowId;
mod wayland;
mod window;

/// Back-end for Slint to run on top of winit event loop.
/// Back-end for Slint to run on top of [`wae`].
///
/// The following are caveats of this back-end:
///
Expand All @@ -35,7 +35,7 @@ mod window;
pub struct SlintBackend {
#[cfg(target_os = "linux")]
wayland: Option<Wayland>,
windows: RefCell<FxHashMap<WindowId, Weak<Window>>>,
windows: RefCell<FxHashMap<WindowId, Weak<SlintWindow>>>,
}

impl SlintBackend {
Expand Down Expand Up @@ -159,8 +159,8 @@ impl slint::platform::Platform for Platform {
})));

// Just panic if people try to create the window when the event loop already exited.
let win = Rc::<Window>::new_cyclic(move |weak| {
Window::new(win, slint::Window::new(weak.clone()), renderer)
let win = Rc::<SlintWindow>::new_cyclic(move |weak| {
SlintWindow::new(win, slint::Window::new(weak.clone()), renderer)
});

assert!(self
Expand All @@ -185,10 +185,6 @@ pub enum BackendError {
#[error("couldn't get global objects from Wayland compositor")]
RetrieveWaylandGlobals(#[source] wayland_client::globals::GlobalError),

#[cfg(target_os = "linux")]
#[error("couldn't bind xdg_wm_base")]
BindXdgWmBase(#[source] wayland_client::globals::BindError),

#[cfg(target_os = "linux")]
#[error("couldn't bind xdg_wm_dialog_v1")]
BindXdgWmDialogV1(#[source] wayland_client::globals::BindError),
Expand Down
25 changes: 6 additions & 19 deletions gui/src/ui/backend/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use wayland_protocols::xdg::shell::client::xdg_wm_base::XdgWmBase;
pub struct Wayland {
queue: RefCell<EventQueue<WaylandState>>,
state: RefCell<WaylandState>,
conn: Connection,
connection: Connection,
}

impl Wayland {
Expand All @@ -29,27 +29,18 @@ impl Wayland {
pub unsafe fn new(display: WaylandDisplayHandle) -> Result<Self, BackendError> {
// Get wayland connection.
let backend = Backend::from_foreign_display(display.display.as_ptr().cast());
let conn = Connection::from_backend(backend);
let connection = Connection::from_backend(backend);

// Get global objects.
let (globals, mut queue) = registry_queue_init::<WaylandState>(&conn)
let (globals, mut queue) = registry_queue_init::<WaylandState>(&connection)
.map_err(BackendError::RetrieveWaylandGlobals)?;
let qh = queue.handle();

// Get xdg_wm_base.
let v = XdgWmBase::interface().version;
let xdg_base: XdgWmBase = globals
.bind(&qh, v..=v, ())
.map_err(BackendError::BindXdgWmBase)?;

// Get xdg_wm_dialog_v1.
let v = XdgWmDialogV1::interface().version;
let xdg_dialog: XdgWmDialogV1 = match globals.bind(&qh, v..=v, ()) {
Ok(v) => v,
Err(e) => {
xdg_base.destroy();
return Err(BackendError::BindXdgWmDialogV1(e));
}
Err(e) => return Err(BackendError::BindXdgWmDialogV1(e)),
};

// Get zxdg_exporter_v2.
Expand All @@ -58,7 +49,6 @@ impl Wayland {
Ok(v) => v,
Err(e) => {
xdg_dialog.destroy();
xdg_base.destroy();
return Err(BackendError::BindZxdgExporterV2(e));
}
};
Expand All @@ -67,7 +57,6 @@ impl Wayland {
let mut state = WaylandState {
xdg_exporter,
xdg_dialog,
xdg_base,
};

queue
Expand All @@ -77,7 +66,7 @@ impl Wayland {
Ok(Self {
queue: RefCell::new(queue),
state: RefCell::new(state),
conn,
connection,
})
}

Expand All @@ -90,7 +79,7 @@ impl Wayland {
}

pub fn connection(&self) -> &Connection {
&self.conn
&self.connection
}

pub fn run(&self) -> impl Future<Output = ()> + '_ {
Expand All @@ -102,7 +91,6 @@ impl Wayland {
pub struct WaylandState {
xdg_exporter: ZxdgExporterV2,
xdg_dialog: XdgWmDialogV1,
xdg_base: XdgWmBase,
}

impl WaylandState {
Expand All @@ -119,7 +107,6 @@ impl Drop for WaylandState {
fn drop(&mut self) {
self.xdg_exporter.destroy();
self.xdg_dialog.destroy();
self.xdg_base.destroy();
}
}

Expand Down
14 changes: 7 additions & 7 deletions gui/src/ui/backend/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use wae::{Signal, WindowHandler, WinitWindow};
use winit::event::{DeviceId, ElementState, InnerSizeWriter, MouseButton};
use winit::window::WindowId;

/// Implementation of [`WindowAdapter`].
pub struct Window {
/// Implementation of [`slint::platform::WindowAdapter`].
pub struct SlintWindow {
winit: Rc<winit::window::Window>,
slint: slint::Window,
renderer: SkiaRenderer,
Expand All @@ -30,7 +30,7 @@ pub struct Window {
preferred_size: Cell<Option<winit::dpi::PhysicalSize<u32>>>,
}

impl Window {
impl SlintWindow {
pub fn new(
winit: Rc<winit::window::Window>,
slint: slint::Window,
Expand Down Expand Up @@ -68,13 +68,13 @@ impl Window {
}
}

impl WinitWindow for Window {
impl WinitWindow for SlintWindow {
fn id(&self) -> WindowId {
self.winit.id()
}
}

impl WindowHandler for Window {
impl WindowHandler for SlintWindow {
fn on_resized(
&self,
new: winit::dpi::PhysicalSize<u32>,
Expand Down Expand Up @@ -260,7 +260,7 @@ impl WindowHandler for Window {
}
}

impl WindowAdapter for Window {
impl WindowAdapter for SlintWindow {
fn window(&self) -> &slint::Window {
&self.slint
}
Expand Down Expand Up @@ -366,7 +366,7 @@ impl WindowAdapter for Window {
}
}

impl WindowAdapterInternal for Window {
impl WindowAdapterInternal for SlintWindow {
fn as_any(&self) -> &dyn Any {
self
}
Expand Down
16 changes: 10 additions & 6 deletions gui/src/ui/linux/dialogs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::PlatformError;
use crate::ui::{DesktopWindow, FileType, SlintBackend};
use ashpd::desktop::file_chooser::{FileFilter, SelectedFiles};
use ashpd::desktop::ResponseError;
Expand All @@ -14,7 +15,7 @@ pub async fn open_file<T: DesktopWindow>(
parent: &T,
title: impl AsRef<str>,
ty: FileType,
) -> Option<PathBuf> {
) -> Result<Option<PathBuf>, PlatformError> {
// Build filter.
let filter = match ty {
FileType::Firmware => FileFilter::new("Firmware Dump").glob("*.obf"),
Expand All @@ -37,15 +38,18 @@ pub async fn open_file<T: DesktopWindow>(
// Get response.
let resp = match req.unwrap().response() {
Ok(v) => v,
Err(ashpd::Error::Response(ResponseError::Cancelled)) => return None,
Err(ashpd::Error::Response(ResponseError::Cancelled)) => return Ok(None),
Err(_) => unimplemented!(),
};

// Get file path.
Some(resp.uris().first().unwrap().to_file_path().unwrap())
Ok(Some(resp.uris().first().unwrap().to_file_path().unwrap()))
}

pub async fn open_dir<T: DesktopWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
pub async fn open_dir<T: DesktopWindow>(
parent: &T,
title: impl AsRef<str>,
) -> Result<Option<PathBuf>, PlatformError> {
// Send the request
let parent = get_parent_id(parent);
let req = SelectedFiles::open_file()
Expand All @@ -63,12 +67,12 @@ pub async fn open_dir<T: DesktopWindow>(parent: &T, title: impl AsRef<str>) -> O
// Get response.
let resp = match req.unwrap().response() {
Ok(v) => v,
Err(ashpd::Error::Response(ResponseError::Cancelled)) => return None,
Err(ashpd::Error::Response(ResponseError::Cancelled)) => return Ok(None),
Err(_) => unimplemented!(),
};

// Get directory path.
Some(resp.uris().first().unwrap().to_file_path().unwrap())
Ok(Some(resp.uris().first().unwrap().to_file_path().unwrap()))
}

fn get_parent_id<P>(parent: &P) -> Parent
Expand Down
10 changes: 7 additions & 3 deletions gui/src/ui/macos/dialogs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::view::get_window;
use super::PlatformError;
use crate::ui::{DesktopWindow, FileType};
use block2::RcBlock;
use futures::StreamExt;
Expand All @@ -18,11 +19,14 @@ pub async fn open_file<T: DesktopWindow>(
parent: &T,
title: impl AsRef<str>,
ty: FileType,
) -> Option<PathBuf> {
) -> Result<Option<PathBuf>, PlatformError> {
todo!();
}

pub async fn open_dir<T: DesktopWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
pub async fn open_dir<T: DesktopWindow>(
parent: &T,
title: impl AsRef<str>,
) -> Result<Option<PathBuf>, PlatformError> {
// Create NSOpenPanel.
let title = NSString::from_str(title.as_ref());
let panel: *mut NSObject = unsafe { msg_send![class!(NSOpenPanel), openPanel] };
Expand Down Expand Up @@ -55,5 +59,5 @@ pub async fn open_dir<T: DesktopWindow>(parent: &T, title: impl AsRef<str>) -> O
unsafe { msg_send![panel, beginSheetModalForWindow:parent completionHandler:cb.deref()] };

// The beginSheetModalForWindow will return immediately so we need a channel here.
rx.next().await.flatten()
Ok(rx.next().await.flatten())
}
6 changes: 3 additions & 3 deletions gui/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl<T: ComponentHandle + WinitWindow> DesktopWindow for T {
use winit::platform::wayland::WindowExtWayland;

let win = WindowInner::from_pub(self.window()).window_adapter();
let win = Window::from_adapter(win.as_ref());
let win = SlintWindow::from_adapter(win.as_ref());

win.winit().xdg_toplevel()
}
Expand Down Expand Up @@ -100,7 +100,7 @@ pub trait RuntimeExt: ComponentHandle {
impl<T: ComponentHandle> RuntimeExt for T {
async fn wait(&self) {
let win = WindowInner::from_pub(self.window()).window_adapter();
let win = Window::from_adapter(win.as_ref());
let win = SlintWindow::from_adapter(win.as_ref());

win.hidden().wait().await;
}
Expand All @@ -119,7 +119,7 @@ macro_rules! impl_wae {
impl WinitWindow for $ty {
fn id(&self) -> WindowId {
let win = WindowInner::from_pub(self.window()).window_adapter();
let win = Window::from_adapter(win.as_ref());
let win = SlintWindow::from_adapter(win.as_ref());

win.id()
}
Expand Down
Loading

0 comments on commit 1bf9eae

Please sign in to comment.