Skip to content

Commit

Permalink
feat(linux): allow resizing undecorated window using touch
Browse files Browse the repository at this point in the history
closes #399
closes #398
  • Loading branch information
amrbashir committed Aug 28, 2021
1 parent 087dbb3 commit 188c059
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changes/linux-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.
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

0 comments on commit 188c059

Please sign in to comment.