WebView2Feedback icon indicating copy to clipboard operation
WebView2Feedback copied to clipboard

Use touch to drag window

Open hbl917070 opened this issue 3 years ago • 55 comments

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

hbl917070 avatar Mar 06 '22 21:03 hbl917070

Thanks for the feature request @hbl917070! I've added this as a scenario on our backlog.

champnic avatar Mar 08 '22 22:03 champnic

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?

champnic avatar Mar 08 '22 22:03 champnic

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.

hbl917070 avatar Mar 09 '22 00:03 hbl917070

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?

champnic avatar Mar 09 '22 19:03 champnic

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.

hbl917070 avatar Mar 09 '22 21:03 hbl917070

Oh I see what you are saying. That's unfortunate, but good info for our scenario that there isn't a workaround available.

champnic avatar Mar 09 '22 23:03 champnic

Hi @hbl917070,

Can you provide details on the customizations you are looking to do for resize regions?

Thanks!

nishitha-burman avatar Feb 24 '23 19:02 nishitha-burman

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.

hbl917070 avatar Feb 24 '23 21:02 hbl917070

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?

champnic avatar Feb 28 '23 20:02 champnic

I opened a new project to test it, and neither the mouse nor the touch can drag the window.

GIF 2023-3-1 上午 05-54-45

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 avatar Feb 28 '23 21:02 hbl917070

@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

champnic avatar Mar 01 '23 18:03 champnic

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>

hbl917070 avatar Mar 01 '23 22:03 hbl917070

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!

nishitha-burman avatar Mar 09 '23 17:03 nishitha-burman

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 avatar Mar 09 '23 18:03 hbl917070

@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!

nishitha-burman avatar Mar 09 '23 20:03 nishitha-burman

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. image

hbl917070 avatar Mar 09 '23 20:03 hbl917070

@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.?

nishitha-burman avatar Mar 09 '23 21:03 nishitha-burman

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 image

hbl917070 avatar Mar 09 '23 22:03 hbl917070

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.

rsegner avatar Mar 15 '23 07:03 rsegner

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

nishitha-burman avatar Mar 21 '23 21:03 nishitha-burman

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>

</Window>`

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.

rsegner avatar Mar 22 '23 07:03 rsegner

Discussing for standardization in https://github.com/w3c/csswg-drafts/issues/7017

bmathwig avatar May 03 '23 21:05 bmathwig

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.

PoetaKodu avatar May 08 '23 18:05 PoetaKodu

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.

champnic avatar May 08 '23 19:05 champnic

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

sc-bai avatar May 09 '23 02:05 sc-bai

@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: image

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>

PoetaKodu avatar May 09 '23 10:05 PoetaKodu

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.

PoetaKodu avatar May 09 '23 10:05 PoetaKodu

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.

champnic avatar May 09 '23 18:05 champnic

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.

champnic avatar May 09 '23 18:05 champnic

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.

sc-bai avatar May 11 '23 06:05 sc-bai