diff --git a/.changes/linux-resizing-undecorated-window-touch.md b/.changes/linux-resizing-undecorated-window-touch.md new file mode 100644 index 0000000000..660fcd026d --- /dev/null +++ b/.changes/linux-resizing-undecorated-window-touch.md @@ -0,0 +1,6 @@ +--- +"wry": patch +--- + +* Fix hovering over an edge of undecorated window on Linux won't change cursor. +* Undecorated window can be resized using touch on Linux. \ No newline at end of file diff --git a/src/webview/webkitgtk/mod.rs b/src/webview/webkitgtk/mod.rs index abc2c3556c..c8bb9c817a 100644 --- a/src/webview/webkitgtk/mod.rs +++ b/src/webview/webkitgtk/mod.rs @@ -4,7 +4,7 @@ use std::rc::Rc; -use gdk::{WindowEdge, RGBA}; +use gdk::{Cursor, EventMask, WindowEdge, RGBA}; use gio::Cancellable; use glib::signal::Inhibit; use gtk::prelude::*; @@ -108,6 +108,47 @@ impl InnerWebView { close_window.gtk_window().close(); }); + webview.add_events( + EventMask::POINTER_MOTION_MASK + | EventMask::BUTTON1_MOTION_MASK + | EventMask::BUTTON_PRESS_MASK + | EventMask::TOUCH_MASK, + ); + webview.connect_motion_notify_event(|webview, event| { + // This one should be GtkWindow + if let Some(widget) = webview.parent() { + // This one should be GtkWindow + if let Some(window) = widget.parent() { + // Safe to unwrap unless this is not from tao + let window: gtk::Window = window.downcast().unwrap(); + if !window.is_decorated() && window.is_resizable() { + if let Some(window) = window.window() { + let (cx, cy) = event.root(); + let edge = hit_test(&window, cx, cy); + // FIXME: calling `window.begin_resize_drag` seems to revert the cursor back to normal style + window.set_cursor( + Cursor::from_name( + &window.display(), + match edge { + WindowEdge::North => "n-resize", + WindowEdge::South => "s-resize", + WindowEdge::East => "e-resize", + WindowEdge::West => "w-resize", + WindowEdge::NorthWest => "nw-resize", + WindowEdge::NorthEast => "ne-resize", + WindowEdge::SouthEast => "se-resize", + WindowEdge::SouthWest => "sw-resize", + _ => "default", + }, + ) + .as_ref(), + ); + } + } + } + } + Inhibit(false) + }); webview.connect_button_press_event(|webview, event| { if event.button() == 1 { let (cx, cy) = event.root(); @@ -118,13 +159,48 @@ impl InnerWebView { // Safe to unwrap unless this is not from tao let window: gtk::Window = window.downcast().unwrap(); if !window.is_decorated() && window.is_resizable() { - // Safe to unwrap since it's a valide GtkWindow - let result = hit_test(&window.window().unwrap(), cx, cy); - - // we ignore the `__Unknown` variant so the webview receives the click correctly if it is not on the edges. - match result { - WindowEdge::__Unknown(_) => (), - _ => window.begin_resize_drag(result, 1, cx as i32, cy as i32, event.time()), + if let Some(window) = window.window() { + // Safe to unwrap since it's a valide GtkWindow + let result = hit_test(&window, cx, cy); + + // we ignore the `__Unknown` variant so the webview receives the click correctly if it is not on the edges. + match result { + WindowEdge::__Unknown(_) => (), + _ => window.begin_resize_drag(result, 1, cx as i32, cy as i32, event.time()), + } + } + } + } + } + } + Inhibit(false) + }); + webview.connect_touch_event(|webview, event| { + // This one should be GtkBox + if let Some(widget) = webview.parent() { + // This one should be GtkWindow + if let Some(window) = widget.parent() { + // Safe to unwrap unless this is not from tao + let window: gtk::Window = window.downcast().unwrap(); + if !window.is_decorated() && window.is_resizable() { + if let Some(window) = window.window() { + if let Some((cx, cy)) = event.root_coords() { + if let Some(device) = event.device() { + let result = hit_test(&window, cx, cy); + + // we ignore the `__Unknown` variant so the window receives the click correctly if it is not on the edges. + match result { + WindowEdge::__Unknown(_) => (), + _ => window.begin_resize_drag_for_device( + result, + &device, + 0, + cx as i32, + cy as i32, + event.time(), + ), + } + } } } }