Skip to content

Commit

Permalink
feat(Windows): resize borderless window (#333)
Browse files Browse the repository at this point in the history
* feat(windows): allow resizing of borderless window

* update imports

* Only resize when the size is different

* Add change file

* Only set the bound once

* Fix examples

* Fix hit test on linex and cargo fmt

* Update way to detect borderless window on Linux

..So it can be detected after the window is changed in runtime.

* Add XXX comment

Co-authored-by: amrbashir <[email protected]>
  • Loading branch information
Ngo Iok Ui (Wu Yu Wei) and amrbashir authored Jul 15, 2021
1 parent 6eb10d4 commit bd10b8e
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 15 deletions.
5 changes: 5 additions & 0 deletions .changes/borderless-resize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": patch
---

Allow resizing of borderless window on Windows
4 changes: 3 additions & 1 deletion examples/custom_titlebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ fn main() -> wry::Result<()> {
document.addEventListener('mousedown', (e) => {
if (e.target.classList.contains('drag-region') && e.buttons === 1) {
window.rpc.notify('drag_window');
e.detail === 2
? window.rpc.notify('maximize')
: window.rpc.notify('drag_window');
}
})
Expand Down
25 changes: 16 additions & 9 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, WindowExt, RGBA};
use gdk::{WindowEdge, RGBA};
use gio::Cancellable;
use glib::{signal::Inhibit, Bytes, Cast, FileError};
use gtk::{BoxExt, ContainerExt, GtkWindowExt, WidgetExt};
Expand Down Expand Up @@ -101,26 +101,33 @@ impl InnerWebView {
webview.connect_button_press_event(|webview, event| {
if event.get_button() == 1 {
let (cx, cy) = event.get_root();
if let Some(window) = webview.get_parent_window() {
let result = crate::application::platform::unix::hit_test(&window, cx, cy);
// This one should be GtkBox
if let Some(widget) = webview.get_parent() {
// This one should be GtkWindow
if let Some(window) = widget.get_parent() {
// Safe to unwrap unless this is not from tao
let window: gtk::Window = window.downcast().unwrap();
if !window.get_decorated() && window.get_resizable() {
// Safe to unwrap since it's a valide GtkWindow
let result = hit_test(&window.get_window().unwrap(), cx, cy);

// this check is necessary, otherwise the webview won't recieve the click properly when resize isn't needed
if result != WindowEdge::__Unknown(8) {
window.begin_resize_drag(result, 1, cx as i32, cy as i32, event.get_time());
// this check is necessary, otherwise the webview won't recieve the click properly when resize isn't needed
if result != WindowEdge::__Unknown(8) {
window.begin_resize_drag(result, 1, cx as i32, cy as i32, event.get_time());
}
}
}
}
}
Inhibit(false)
});

// Gtk application window can only contain one widget at a time.
// In tao, we add a gtk box if menu bar is required. So we check if
// In tao, we add a GtkBox to pack menu bar. So we check if
// there's a box widget here.
if let Some(widget) = window.get_children().pop() {
let vbox = widget.downcast::<gtk::Box>().unwrap();
vbox.pack_start(&*webview, true, true, 0);
} else {
window.add(&*webview);
}
webview.grab_focus();

Expand Down
55 changes: 50 additions & 5 deletions src/webview/webview2/win32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,14 @@ impl InnerWebView {

// Initialize scripts
w.add_script_to_execute_on_document_created(
"window.external={invoke:s=>window.chrome.webview.postMessage(s)}",
r#"
window.external={invoke:s=>window.chrome.webview.postMessage(s)};
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__'));
"#,
|_| (Ok(())),
)?;
for js in attributes.initialization_scripts {
Expand All @@ -116,6 +123,46 @@ impl InnerWebView {
let rpc_handler = attributes.rpc_handler.take();
w.add_web_message_received(move |webview, args| {
let js = args.try_get_web_message_as_string()?;
if js == "__WEBVIEW_LEFT_MOUSE_DOWN__" || js == "__WEBVIEW_MOUSE_MOVE__" {
if !window_.is_decorated() && window_.is_resizable() {
use winapi::um::winuser::{
HTBOTTOM, HTBOTTOMLEFT, HTBOTTOMRIGHT, HTLEFT, HTRIGHT,
HTTOP, HTTOPLEFT, HTTOPRIGHT, HTCLIENT, GetCursorPos,
};
use crate::application::{window::CursorIcon,platform::windows::hit_test};

let (cx, cy);
unsafe {
let mut point = std::mem::zeroed();
GetCursorPos(&mut point);
cx = point.x;
cy = point.y;
};
let result = hit_test(window_.hwnd() as _, cx, cy);
let cursor = match result {
HTLEFT => CursorIcon::WResize,
HTTOP => CursorIcon::NResize,
HTRIGHT => CursorIcon::EResize,
HTBOTTOM => CursorIcon::SResize,
HTTOPLEFT => CursorIcon::NwResize,
HTTOPRIGHT => CursorIcon::NeResize,
HTBOTTOMLEFT => CursorIcon::SwResize,
HTBOTTOMRIGHT => CursorIcon::SeResize,
_ => CursorIcon::Arrow,
};
window_.set_cursor_icon(cursor);

if js == "__WEBVIEW_LEFT_MOUSE_DOWN__" {
// this check is necessary, otherwise any window dragging implementation won't work
if result != HTCLIENT {
window_.begin_resize_drag(result);
}
}
}
// these are internal messages, rpc_handlers don't need it so exit early
return Ok(());
}

if let Some(rpc_handler) = &rpc_handler {
match super::rpc_proxy(&window_, js, rpc_handler) {
Ok(result) => {
Expand Down Expand Up @@ -240,6 +287,7 @@ impl InnerWebView {
}
}
});
// TODO: OnceCell into_inner for controller

Ok(Self {
controller,
Expand All @@ -263,17 +311,14 @@ impl InnerWebView {
let hwnd = hwnd as HWND;

// Safety: System calls are unsafe
// XXX: Resizing on Windows is usually sluggish. Many other applications share same behavior.
unsafe {
let mut rect = std::mem::zeroed();
GetClientRect(hwnd, &mut rect);
if let Some(c) = self.controller.get() {
rect.left = rect.left + 1;
c.put_bounds(rect)?;
rect.left = rect.left - 1;
c.put_bounds(rect)?;
}
}

Ok(())
}

Expand Down

0 comments on commit bd10b8e

Please sign in to comment.