Skip to content

Commit

Permalink
feat(linux): allow resizing undecorated window using touch, closes #399
Browse files Browse the repository at this point in the history
… (#402)

* feat(linux): allow resizing undecorated window using touch
closes #399

* fix windows

* update custom_titlebar example

* revert windows changes
  • Loading branch information
amrbashir authored Sep 16, 2021
1 parent 3abe0bc commit 66ee183
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 15 deletions.
6 changes: 6 additions & 0 deletions .changes/resizing-undecorated-window-touch.md
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 1 addition & 5 deletions examples/custom_titlebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,7 @@ fn main() -> wry::Result<()> {
window.set_minimized(true);
}
if req.method == "maximize" {
if window.is_maximized() {
window.set_maximized(false);
} else {
window.set_maximized(true);
}
window.set_maximized(!window.is_maximized());
}
if req.method == "close" {
let _ = proxy.send_event(UserEvents::CloseWindow(window.id()));
Expand Down
92 changes: 84 additions & 8 deletions src/webview/webkitgtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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();
Expand All @@ -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(),
),
}
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/webview/webview2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl InnerWebView {
window.addEventListener('mousedown', (e) => {
if (e.buttons === 1) window.chrome.webview.postMessage('__WEBVIEW_LEFT_MOUSE_DOWN__')
});
window.addEventListener('mousemove', () => window.chrome.webview.postMessage('__WEBVIEW_MOUSE_MOVE__'));
window.addEventListener('mousemove', (e) => window.chrome.webview.postMessage('__WEBVIEW_MOUSE_MOVE__'));
"#,
|_| (Ok(())),
)?;
Expand Down Expand Up @@ -158,7 +158,7 @@ impl InnerWebView {
window_.set_cursor_icon(cursor);
}

if js == "__WEBVIEW_LEFT_MOUSE_DOWN__" {
if js == "__WEBVIEW_LEFT_MOUSE_DOWN__" {
// we ignore `HTCLIENT` variant so the webview receives the click correctly if it is not on the edges
// and prevent conflict with `tao::window::drag_window`.
if result != HTCLIENT {
Expand Down

0 comments on commit 66ee183

Please sign in to comment.