Open hbl917070 opened 2 years ago
Thanks for the feature request @hbl917070! I've added this as a scenario on our backlog.
Looking at the solution in #200, it looks like they are only listening to the mousedown
event. Can you try using pointerdown
and other pointer events instead and see if that works for touch?
JavaScript event pointerdown
, touchstart
, mousedown
cannot drag the window under the touch screen.
I use it in C#
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool ReleaseCapture();
public const int WM_SYSCOMMAND = 0x0112;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
public void Drag(){
ReleaseCapture();
SendMessage(handle, WM_SYSCOMMAND, (int)0xF009, 0);
}
In WPF or winForm, I can drag the window by calling Drag()
in MouseDown
.
In webview2 or cef, I can use the mouse to trigger mousedown
, thereby dragging the window.
In webview2 or cef, I use touchscreen to trigger touchstart, and make sure Drag()
is executed, but I can't drag the window.
This is just my guess. When Chromium receives a touch command, Chromium will intercept the touch command, so that touch does not hold for Windows systems.
Just to be clear, my suggestion was to change the code in #200 from this:
window.addEventListener('DOMContentLoaded', () => {
document.body.addEventListener('mousedown', evt => {
const { target } = evt;
const appRegion = getComputedStyle(target)['-webkit-app-region'];
if (appRegion === 'drag') {
chrome.webview.hostObjects.sync.eventForwarder.MouseDownDrag();
evt.preventDefault();
evt.stopPropagation();
}
});
});
to this:
window.addEventListener('DOMContentLoaded', () => {
document.body.addEventListener('pointerdown', evt => {
const { target } = evt;
const appRegion = getComputedStyle(target)['-webkit-app-region'];
if (appRegion === 'drag') {
chrome.webview.hostObjects.sync.eventForwarder.MouseDownDrag();
evt.preventDefault();
evt.stopPropagation();
}
});
});
By changing mousedown
to pointerdown
. I don't think anything else needs to change. Is that not working for you?
Yes, after my testing, this doesn't work with touchscreens.
Under normal circumstances, when using touch on a touch screen, the mouse cursor will move with the touch.
But in the case of web page, using touch doesn't make the mouse cursor move,
If the mouse coordinates have not changed, then the SendMessage
of C# cannot drag the window.
https://youtu.be/ZIOraK74Png In the first 15 seconds of the video, touch in the webpage will not change the coordinates of the mouse. In the second half of the video, I dragged the title bar of the browser directly, and the mouse followed the touch.
Oh I see what you are saying. That's unfortunate, but good info for our scenario that there isn't a workaround available.
Hi @hbl917070,
Can you provide details on the customizations you are looking to do for resize regions?
Thanks!
I hope that all UI of the program can be presented through WebView2, including the window title bar. But WebView2 can be embedded in WinForm, WPF, UWP… Therefore, the solution needed may be a new window object or a new C# project?
For example
WebView2Window window = new WebView2Window();
window.Style = WebView2WindowStyle.NoTitleBar;
window.Show();
WebView2 wv2 = window.Webview;
wv2.CoreWebView2.Navigate("https://www.bing.com");
WebView2Window is a window object that is similar to Form
,
except that it only contains one WebView2 object inside
and can remove the window title bar.
The window also supports full transparency.
Then, following Electron’s approach, you can use CSS --webkit-app-region:drag
to enable a DIV to drag the window.
You should now be able to use app-region: drag
in window-hosted scenarios (Win32, .NET WPF/Winforms - NOT UWP or WinAppSDK yet), and have that work for touch as well. Can you give that a try and let me know if it's not working?
I opened a new project to test it, and neither the mouse nor the touch can drag the window.
Project: net 4.7 WinForm
OS: Windows 10 (19045.2673)
WebView2 version: 1.0.1587.40
WebView2 userAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.57
C#
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
webView21.Source = new Uri("file:///C:/Users/u1/Desktop/moveTest.html");
}
}
moveTest.html
<!DOCTYPE html>
<html>
<body>
<style>
#move {
width: 300px;
height: 300px;
background-color: rgb(100, 200, 200);
--app-region: drag;
-app-region: drag;
app-region: drag;
--webkit-app-region: drag;
-webkit-app-region: drag;
webkit-app-region: drag;
}
</style>
<div id="move"> </div>
</body>
</html>
@hbl917070 Sorry for the confusion - looks like it requires a flag to enable it currently. Can you try setting this additional browser argument?
--enable-features=msWebView2EnableDraggableRegions
It worked, mouse and touch can drag the window!
In addition, if there is a solution to drag the border to change the size of the window, then everything will be perfect.
C#
public partial class Form1 : Form {
WebView2 webView21;
public Form1() {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
InitWebview();
}
private async void InitWebview() {
webView21 = new WebView2();
this.Controls.Add(webView21);
webView21.Dock = DockStyle.Fill;
string arg = @"--enable-features=""msWebView2EnableDraggableRegions""";
var opts = new CoreWebView2EnvironmentOptions { AdditionalBrowserArguments = arg };
var webView2Environment = await CoreWebView2Environment.CreateAsync(null, null, opts);
await webView21.EnsureCoreWebView2Async(webView2Environment);
webView21.Source = new Uri("file:///C:/Users/u1/Desktop/moveTest.html");
}
}
moveTest.html
<!DOCTYPE html>
<html>
<body>
<style>
#move {
app-region: drag;
width: 300px;
height: 300px;
background-color: rgb(100, 200, 200);
}
</style>
<div id="move"></div>
</body>
</html>
Hi @hbl917070,
Glad that worked for you! Can you please expand on the ask to have support for dragging the border to change the size of the window? What properties are you looking to customize for the resize regions? The OS has non client area resize regions, is there a reason you are expanding your app to the OS's non client area in the left, right, bottom sides? Also, if WebView2 by default support the borders as resize regions, does that address your needs or are you looking to configure dimensions of the divs for the resize regions?
Thanks!
My requirement is to use HTML to draw the whole UI, including TitleBar, window border, and window support translucent background color.
I released an open source project, Tiefsee4, which implements the above features.
In Tiefsee4, I use WinForm to place WebView2.
After processing WinForm into a state without TitleBar and window border, WinForm also lost the ability to drag the border to change the size of the window.
So I need a solution that can be triggered inside the WebView2 to change the window size, similar to CSS app-region:drag;
.
Maybe can extend the app-region
properties like this image, e.g. app-region:drag-top-right
means drag the top-right corner of the window to change the window size
@hbl917070 thank you for the context! Are you looking to configure dimensions of the drag regions or are you okay with an option where WV2 by default provides those regions?
Thanks!
It is of course the best solution to allow developers to configure freely. For example, I usually design the drag regions in the corner to be larger. And different apps may need different size of drag regions.
@hbl917070 thank you for the context! So in addition to the dimensions do you also want to configure other factors such as color, transparency, opacity, etc.?
If the CSS app-region
is used to bind the drag regions, then I think the style should not be a problem.
However, binding a DIV to a drag regions will prevent the DIV from being clicked, which will result in the CSS cursor
not being triggered.
So need to switch the cursor shape according to the type of dragging
For example
When the cursor enters the app-region:drag-bottom-right
region, the cursor will appear as cursor:nw-resize
This post has been very helpful. I didn't realize that WebView2 now supported --app-region: drag
.
@nishitha-burman @champnic I have the same issue with resizing the window. The problem is that I use WindowChrome
class in WPF to create a 'frameless' WebView window. The WebView does not respect the ResizeBorderThickness
property of this class.
In order to get around it I added a border around the WebView which has provided users with a very unforgiving 2 pixels for resizing. I don't really need the same level of customization as described above, however, being able to resize the window from a frameless WebView window would be amazing.
Hi @rsegner,
Thank you for the feedback! Can you please provide details on how you are adding a border around the WebView and how you are making it draggable?
Thanks, Nishitha
Hi @nishitha-burman,
Sure thing.
This is the XAML for my frameless webview window.
`<Window x:Class="WebView.WebViewWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Window"
Height="450" Width="800"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="40" ResizeBorderThickness="8"/>
</WindowChrome.WindowChrome>
<Border Background="{StaticResource primaryColor}"
BorderBrush="{StaticResource primaryColor}"
BorderThickness="2">
<Grid>
<ContentPresenter x:Name="webViewPresenter" Visibility="Hidden"/>
<ContentPresenter x:Name="loaderPresenter" Visibility="Visible"></ContentPresenter>
</Grid>
</Border>
`
The content presenter webViewPresenter
contains a WebView that is originally hidden, and then shown once the page is fully loaded.
Before the WebView is shown we are able to resize the window from anywhere inside the 8 pixels denoted by ResizeBorderThickness
property on the WindowChrome
class.
However, after the WebView is made visible we can only resize from the 2px border surrounding the WebView. Ideally, I would like to remove this border and retain the 8px resize border.
Discussing for standardization in https://github.com/w3c/csswg-drafts/issues/7017
I'd like this feature too. I'm using WebView2 in my native Win32 application and it captures WM_NCHITTEST
event, so I cannot even override the dragging behavior in borderless mode. Having any way of achieving this effect would be incredibly useful, because right now we cannot even customize what events are passed to the webview.
You should now be able to use app-region: drag
CSS attribute when WebView2 is using HWND hosting (Win32, .NET WPF/Winforms - NOT UWP or WinAppSDK yet), and have that work for touch as well.
You also need to set the additional browser arg --enable-features=msWebView2EnableDraggableRegions
.
Hi, @champnic , I User WebView2 With Win32. it can drag window with --enable-features=msWebView2EnableDraggableRegions, but it can be work in WebView2 runtim version 103.xxx. with runtime version 100.xx, it can not work, you know how to fix it? thanks
@champnic It doesn't work for me at all. Have I missed something? This is pretty much the simplest example of a webview running in native Win32 app: https://pastebin.com/4KhVbAMK
I went to C:\Program Files (x86)\Microsoft\EdgeWebView\Application
and it seems that I have version 113:
I use the latest WebView2 library downloaded from NuGet (1.0.1774.30
).
The HTML document I'm navigating to is just a fully red page that has --app-region: drag
set to body
CSS:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html, body, #root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
body {
background-color: red;
--app-region: drag;
}
</style>
</head>
<body>
</body>
</html>
Oh my god, I managed to get it working by changing this:
body {
background-color: red;
--app-region: drag;
}
to this:
body {
background-color: red;
--app-region: drag;
-webkit-app-region: drag;
}
:eyes:
I think that this should be definitely mentioned somewhere in the docs (or maybe it is documented and I missed it?). I searched the web really thoroughly before and experimented with various options but this changes everything.
Aha - I'm really sorry, the CSS should be app-region: drag
, not --app-region: drag
. I'm updating this thread to fix everywhere I wrote that erroneously.
Hi, @champnic , I User WebView2 With Win32. it can drag window with --enable-features=msWebView2EnableDraggableRegions, but it can be work in WebView2 runtim version 103.xxx. with runtime version 100.xx, it can not work, you know how to fix it? thanks
This support requires runtime 110+, so I wouldn't expect it to work on 103 or 100.
Hi, @champnic , I User WebView2 With Win32. it can drag window with --enable-features=msWebView2EnableDraggableRegions, but it can be work in WebView2 runtim version 103.xxx. with runtime version 100.xx, it can not work, you know how to fix it? thanks
This support requires runtime 110+, so I wouldn't expect it to work on 103 or 100.
yeah, I got it. i made a mistake,103+ and 100+ is sdk version. Now, less than 110, Move the window by passing the mouse position to drag the window and 110++ by msWebView2EnableDraggableRegions flag. thanks for your replay.
I just tried this and noticed a really weird side-effect: right clicking on an app-region: drag
element pops up the default window caption menu! The non-draggable regions will present the standard webview2 context menu when right clicked.
Windows 11 / 114.0.1823.43 / win32
I try msWebView2EnableDraggableRegions in the WinUI3 C# unpackaged app, it can not work, but it can work in c++ WinUI3 project, is it a bug of WinUI3?
@leaanthony Ah - it may be the default behavior expects it to be a title bar. Can you open that as a new issue?
@wangqiang871104 Draggable regions are only working for Windowed/CoreWebView2Controller scenarios at the moment. The WinUI 2 and WinUI 3 controls are built upon visual hosting/CoreWebView2CompositionController, and so don't have support yet. We are working on enabling that support, but it will require a WinUI update before that happens.
@leaanthony Ah - it may be the default behavior expects it to be a title bar. Can you open that as a new issue?
Thanks @champnic - Ticket opened if anyone else is interested: https://github.com/MicrosoftEdge/WebView2Feedback/issues/3565
I just tried this and noticed a really weird side-effect: right clicking on an
app-region: drag
element pops up the default window caption menu! The non-draggable regions will present the standard webview2 context menu when right clicked. Windows 11 / 114.0.1823.43 / win32
you can try remove WS_SYSMENU, sample code : SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & (0xFFFFFFFF ^ WS_SYSMENU));
@leaanthony Ah - it may be the default behavior expects it to be a title bar. Can you open that as a new issue?
@wangqiang871104 Draggable regions are only working for Windowed/CoreWebView2Controller scenarios at the moment. The WinUI 2 and WinUI 3 controls are built upon visual hosting/CoreWebView2CompositionController, and so don't have support yet. We are working on enabling that support, but it will require a WinUI update before that happens.
thanks,does this update on the roadmap, when can I get this update or any workaround can work now?
you can try remove WS_SYSMENU, sample code : SetWindowLong(hwnd, GWL_STYLE,\nGetWindowLong(hwnd, GWL_STYLE) & (0xFFFFFFFF ^ WS_SYSMENU));
Thanks, that works to remove the menu, but then the default menu doesn't work either
@hbl917070 Sorry for the confusion - looks like it requires a flag to enable it currently. Can you try setting this additional browser argument?
--enable-features=msWebView2EnableDraggableRegions
FYI - We now have a setting available in our prerelease SDKs (should be in the next release SDK as well) for enabling drag regions, so you won't need to use the command line flag moving forwards: https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2settings.isnonclientregionsupportenabled?view=webview2-dotnet-1.0.2415-prerelease&preserve-view=true
@champnic Hey, the app-region: drag;
and the additional browser args work well. I can now drag and double-click to maximize like a regular window. However, could you add an attribute or API to enable resizing the window by dragging the borders? Also, when I double-click the div title bar to maximize/restore, can I get a callback or access the current maximize/restore state in JavaScript (I want to display the button icon in my custom title bar)? Much appreciated!
Hey @EarzuChan - for border resize, typically the easiest way to accomplish this is to resize the WebView2 to not go all the way to the border of the parent window. This allows the regular parent window to hit-test and handle the border for resizing behaviors.
For an event on maximize/restore, you should be able to detect the state change in the host app, and then send that into the JS (for example, using ExecuteScript
) to display your button.
hello,I'm implementing a title bar in html,Now whether there is a good way to hide the menu,When I right-click, I do not want to see the system default menu items.:“Restore”、"Move"、"Size"、"Minimize"、"Maximize"、"Close"
@Noahs007 Right now that's expected behavior. To achieve dragging like a normal titlebar we tell Windows that this is a titlebar when it does hit-testing. Default Windows behavior is to show those menu items when right-clicking on a titlebar.
Hey honey, is the problem of webview2 blocking my stretching of my title-bar-less window border solved?
@Noahs007 Right now that's expected behavior. To achieve dragging like a normal titlebar we tell Windows that this is a titlebar when it does hit-testing. Default Windows behavior is to show those menu items when right-clicking on a titlebar.
Ok thanks for your answer, I'm looking forward to a future update of webview2 to have a good way to hide the menu item showing the expected behavior, since the default design of this menu is different from my html page design style.
@champnic I'm trying to follow progress on having this in a WinUI3 application, but not finding anything. Is this issue here also the tracking issue for that (or is it possible to get any timeline for it)?
This would be work done by the WinAppSDK team for their WinUI3 control. I'm following up with that team to see if they have a timeline for this support. Thanks!
This would be work done by the WinAppSDK team for their WinUI3 control. I'm following up with that team to see if they have a timeline for this support. Thanks!
@champnic Thank you for your hard work. Has the issue with resizing the window by dragging the border been resolved for the WPF platform when controls cover the entire window without a title bar?
@champnic Thank you for your hard work. Has the issue with resizing the window by dragging the border been resolved for the WPF platform when controls cover the entire window without a title bar?
No. For now the recommendation is still to not cover the entire app window to allow the drag regions to work properly.
@champnic Thank you for your hard work. Has the issue with resizing the window by dragging the border been resolved for the WPF platform when controls cover the entire window without a title bar?
No. For now the recommendation is still to not cover the entire app window to allow the drag regions to work properly.
Awww man. By the way, can it be solved if I rewrite it with other frameworks, such as winui3 or winform or Win32? That is, I want to have the rounded corner window style with shadow of Windows 11 and I do want to cover the whol frame, just like electron.
Winform can allow WebView2 to completely cover the window. When running on Windows 11, it can even utilize the system's native window rounded corners and shadows, and even the Mica effect is no problem. I have an open-source project that has already implemented these features. https://github.com/hbl917070/Tiefsee4
However, I haven't done a good job of encapsulating these window features. These codes are mixed with other functionalities, so they might be a bit hard to find.
I use webview2 to make the entire UI of the program, including the title bar of the window is also HTML. Electron can use
--webkit-app-region: drag;
in CSS, but webview2 does not support it.https://github.com/MicrosoftEdge/WebView2Feedback/issues/200#issuecomment-633061172 I tried to use this method to implement window dragging, but this method only works with the mouse, and the touch screen will not respond.
Microsoft Teams on Windows 11 also uses webview2, I use a surface laptop 3 and I can't drag Microsoft Teams on the touch screen.
If possible, would like to be able to support CSS like
--webkit-app-region: drag-top;
so that the window can be resized.AB#38450196