WindowsAppSDK icon indicating copy to clipboard operation
WindowsAppSDK copied to clipboard

After setting `AppWindowTitleBar.ExtendsContentIntoTitleBar` on Windows 10, the title bar cannot drag (v1.2-preview1)

Open Scighost opened this issue 3 years ago • 20 comments

Describe the bug

This is a bug in WindowsAppSDK v1.2 preview1, when I set AppWindowTitleBar.ExtendsContentIntoTitleBar, the title bar can't be dragged. In fact, this problem also happens when not using SetDragRectangles.

titleBar = appWindow.TitleBar;
titleBar.ExtendsContentIntoTitleBar = true;
titleBar.SetDragRectangles(new RectInt32[] { new RectInt32(0, 0, 10000, 48) });

https://user-images.githubusercontent.com/61003590/190835485-207620f4-b75c-45e2-a896-768e7cf28276.mp4

Steps to reproduce the bug

  1. Create new project
  2. Update package
  3. Write some code
  4. Run

Expected behavior

The title bar can be dragged.

Screenshots

No response

NuGet package version

1.2.220902.1-preview1

Packaging type

Packaged (MSIX)

Windows version

Windows 10 version 21H2 (19044, November 2021 Update)

IDE

Visual Studio 2022-preview

Additional context

<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.2.220902.1-preview1" />

Scighost avatar Sep 17 '22 01:09 Scighost

Did you add a Manifest ? (maybe similar to #7292)

castorix avatar Sep 17 '22 07:09 castorix

Did you add a Manifest ? (maybe similar to #7292)

Yes, app.manfest is the default manifest file when creating a packaged project.

Compared to that issue, this demo was deployed by MSIX package and the caption button is clickable.

https://user-images.githubusercontent.com/61003590/190846612-6783d976-571d-419a-875f-d5506ae98d74.mp4

Scighost avatar Sep 17 '22 07:09 Scighost

Did you add a Manifest ? (maybe similar to #7292)

Yes, app.manfest is the default manifest file when creating a packaged project.

With the lines for OS >=Windows 8 ? (for layered child windows), like in the sample I had posted : app.manifest

castorix avatar Sep 17 '22 08:09 castorix

With the lines for OS >=Windows 8 ? (for layered child windows), like in the sample I had posted : app.manifest

I changed the manifest content to be the same as yours, but it still doesn't work.

Scighost avatar Sep 17 '22 11:09 Scighost

With the lines for OS >=Windows 8 ? (for layered child windows), like in the sample I had posted : app.manifest

I changed the manifest content to be the same as yours, but it still doesn't work.

Does the same problem appear if you compile my sample ? (I had only tested with Windows app SDK 1.1.0)

castorix avatar Sep 17 '22 11:09 castorix

Does the same problem appear if you compile my sample ? (I had only tested with Windows app SDK 1.1.0)

Your project ran successfully on Windows 10, but it uses Window.ExtendsContentIntoTitleBar that is not I want. I'm testing AppWindowTitleBar in SDK 1.2 preview 1, however it doesn't work well.

Scighost avatar Sep 17 '22 11:09 Scighost

One suggestion is to make the drag rectangle actually fit within the bounds of the window. The way I normally do it which works with Windows 11 is:

void MainWindow::set_drag_region()
    {
        auto title_bar = m_app_window.TitleBar();
        
        Windows::Graphics::RectInt32 drag_rect{};
        drag_rect.X = static_cast<int32_t>(title_bar.LeftInset());
        drag_rect.Y = 0;
        drag_rect.Height = static_cast<int32_t>(title_bar.Height());
        drag_rect.Width = static_cast<int32_t>(m_app_window.Size().Width - title_bar.RightInset());

        std::array<Windows::Graphics::RectInt32, 1> drag_rects{};
        drag_rects[0] = drag_rect;
        title_bar.SetDragRectangles(drag_rects);
    }

https://user-images.githubusercontent.com/52577874/190876460-00b7ee4c-7d6b-40d3-a57e-30c78a839bef.mp4 App2.zip

This works normally on Windows 11. While this is C++, this should be translatable to C# without issues.

DarranRowe avatar Sep 17 '22 21:09 DarranRowe

Your project ran successfully on Windows 10, but it uses Window.ExtendsContentIntoTitleBar that is not I want. I'm testing AppWindowTitleBar in SDK 1.2 preview 1, however it doesn't work well.

But MSDN says : Title bar customization APIs are currently supported on Windows 11 only. You should check AppWindowTitleBar.IsCustomizationSupported in your code before you call these APIs to ensure your app doesn't crash on other versions of Windows. See Title bar customization for more info.

castorix avatar Sep 18 '22 04:09 castorix

@castorix The release notes for 1.2 preview 1 states that full customisation is available on Windows 10.

DarranRowe avatar Sep 18 '22 09:09 DarranRowe

@castorix The release notes for 1.2 preview 1 states that full customisation is available on Windows 10.

Ah thanks, I'm still at 1.1.0...

castorix avatar Sep 18 '22 09:09 castorix

I see that we can set drag area on Window 11. However, it can not handle double click action of titlebar:

  • Double click to maximized/restore

tranhuynhthaitrung avatar Sep 21 '22 04:09 tranhuynhthaitrung

I see that we can set drag area on Window 11. However, it can not handle double click action of titlebar:

  • Double click to maximized/restore

Double click is available in the original title bar area (the top 32 px of window, 100% scale) not the custom draggable area.

Scighost avatar Sep 21 '22 06:09 Scighost

@tranhuynhthaitrung AppWindowTitleBar.PreferredHeightOption allows you to extend it. But to be honest, the Windows design guidelines state that title bars should either be 32 or 48 pixels. This class seems to conform to that. If you are looking for a general purpose API, your best option is still using DWM.

DarranRowe avatar Sep 21 '22 16:09 DarranRowe

@tranhuynhthaitrung AppWindowTitleBar.PreferredHeightOption allows you to extend it. But to be honest, the Windows design guidelines state that title bars should either be 32 or 48 pixels. This class seems to conform to that. If you are looking for a general purpose API, your best option is still using DWM.

@DarranRowe I also try to receive native event of window to handle caption area. Is it same DWM of your mean ? Could you provide more advance suggestion :D

tranhuynhthaitrung avatar Sep 22 '22 03:09 tranhuynhthaitrung

I believe the issue you are having is because you have not called SetTitleBar after ExtendsContentIntoTitleBar.

I have created a minimal example that you can find here: https://github.com/onslauth/TitleBarTestApp

If you run the application as is, you will see the title bar is discoloured, but you will be able to click and drag. image

You can fix that by commenting out the following code. But you will notice that the control added to 'GridTitleBar' is no longer visible in the top left: App.xaml:

<!-- <SolidColorBrush x:Key="WindowCaptionBackground">Orange</SolidColorBrush> -->

image

You can solve that problem, by setting the WindowCaptionBackground colour to Transparent as follows:

<SolidColorBrush x:Key="WindowCaptionBackground">Transparent</SolidColorBrush>

Now the controls in GridTitleBar are visible and the title bar has the same colour as the rest of the application. image

At this point you can customise the title bar by adding controls to GridTitleBar in MainWindow.xaml. Here is a Youtube video that provides a good example: https://www.youtube.com/watch?v=rhYdNuBkqtE

After this, you might run into some issues that I am experiencing and for which I have opened a ticket: https://github.com/microsoft/WindowsAppSDK/issues/2987

Hope that helps.

onslauth avatar Sep 22 '22 13:09 onslauth

@onslauth This is why the various colour properties exists for AppWindowTitleBar. You can set these to transparent and you don't have to use the Xaml SetTitleBar. But that also doesn't affect the max/restore double click.

@tranhuynhthaitrung Again, that all depends on what you want/need.

https://user-images.githubusercontent.com/52577874/191871459-217ccdee-6faa-42a7-88ae-65d760bc7c77.mp4

https://user-images.githubusercontent.com/52577874/191871480-9441efeb-1fc7-4128-a5f5-2c3643d34aa5.mp4

If all you want is the regular sized title bars, then you don't need to do anything. The region which it accepts the double click is the width of the title bar between AppWindowTitleBar.LeftInsert and AppWindowTitleBar.RightInsert and the height of the title bar up to AppWindowTitleBar.Height.

If you want much more control over this, the old Custom Window Frame Using DWM is still what you need to base your code on to fully customise the title bar.

DarranRowe avatar Sep 23 '22 00:09 DarranRowe

@DarranRowe ok I see. However, we can not hide miximized/maximized button when we use ExtendsContentIntoTitleBar

I see that it is different issue and updated in preview version :D

tranhuynhthaitrung avatar Sep 23 '22 03:09 tranhuynhthaitrung

@tranhuynhthaitrung That is controlled by the window style.

Using the raw Windows API to create the window.

https://user-images.githubusercontent.com/52577874/191891259-69f3ceec-7061-4119-86bd-b1c3f839a473.mp4

https://user-images.githubusercontent.com/52577874/191891277-bf3538f5-0a20-4ec8-87b2-f82e1bd871e0.mp4

WS_OVERLAPPEDWINDOW is defined in WinUser.h as

#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED     | \
                             WS_CAPTION        | \
                             WS_SYSMENU        | \
                             WS_THICKFRAME     | \
                             WS_MINIMIZEBOX    | \
                             WS_MAXIMIZEBOX)

As you can see, if you exclude those styles then the minimize and maximize buttons also go away. If you want to do this exclusively with the Windows App SDK, I suggest you look at the presenter. The overlapped presenter has the IsMinimizable and IsMaximizable properties.

DarranRowe avatar Sep 23 '22 04:09 DarranRowe

@onslauth Thanks for your answer, but that's not what I want. I'm testing AppWindowTitleBar on Windows 10, this api was mentioned in v1.2 preview 1 release notes but it still doesn't work.

Scighost avatar Sep 23 '22 08:09 Scighost

Well, I finally got around to testing a sample on Windows 10. It drags properly and double clicking on the title bar causes it to maximise and restore properly. In fact, the Windows 11 code is what worked without issue on Windows 10.

WindowTest2.zip

This is the Windows API project that I used to do this. As a note, it is still set to self contained, but that shouldn't make a difference, the system that I was testing this on didn't have 1.2 preview 1 installed on it. If you want to be sure, just remove the WindowsAppSDKSelfContained element from the .vcxproj file.

DarranRowe avatar Sep 23 '22 16:09 DarranRowe

This issue still exists in WAS version 1.2.220930.4-preview2. Only Min/Max/Restore/Close buttons work, the preserved area left to the min button can't be dragged. Double click doesn't work too.

Lightczx avatar Oct 08 '22 01:10 Lightczx

I wish you would actually provide information besides going "it doesn't work".

https://user-images.githubusercontent.com/52577874/194714446-1f0c1677-917a-4b14-a59a-c86049436e0d.mp4

As I have said, it works under Windows 10.

DarranRowe avatar Oct 08 '22 15:10 DarranRowe

@DarranRowe your c++ code works, but my c# code doesn't. Probably the WinRT projection issue.

Lightczx avatar Oct 09 '22 01:10 Lightczx

@Lightczx No, it isn't a projection issue.

Admittedly, I have been trying to nudge the original poster towards re-evaluating assumptions for a little while. As such, I did hold back a little bit of information in that last post. You see, the simple fact that a video and three lines of code was given is just terrible for a bug report. The assumption that "Windows App SDK" implies a certain feature set is bad. What's more, actually providing full information allows the developers to properly evaluate and fix any bugs.

So, let's go a bit further in depth as to the nature of the bug. The sample that I was showing was the custom title bar in its purest form. It was a Windows API application that uses the AppWindow and AppWindowTitleBar classes to enable the use of a custom title bar. Importantly, this sample was not created using the WinUI 3 application template. In this case, I have not seen any problems using ExtendsContentIntoTitleBar and SetDragRectangles.

My testing of this is incomplete though. I don't really have proper developer access to a Windows 10 system right now. This is why my initial testing went towards the simplest application, a Windows API application using the AppWindow class to customise the title bar first. This does test the title bar code without interference from anything else though.

I did, however, see this problem when the ExtendsContentIntoTitleBar was used in a WinUI 3 application. This is the bit of information I held back for a bit. The sample that I did see this issue on didn't call SetTitleBar, so I'm not sure if that makes any difference. This was something that I was only able to test very recently, since I don't have proper access to a Windows 10 system right now. This information is actually important because this could mean that it is a WinUI 3 bug, but at the very least, knowing that it is the interaction between the two helps narrow down where the problem is.

This is actually why providing a sample that reproduces the problem is very useful. One big step towards fixing an issue is actually reproducing the issue. A sample that reproduces the problem adds context to the bug. You cannot assume that a developer is going to be able to reproduce the issue, and if the issue is not reproducible then it can't be fixed. This is especially true in cases where you assume certain conditions, but those conditions don't necessarily have to be true. This is one of those cases, the assumption that "Windows App SDK" implies "WinUI 3" is a bad assumption, since as I have demonstrated, it is possible to use the AppWindow/AppWindowTitleBar classes independently of WinUI 3, and the issue doesn't appear if it is used independently of WinUI 3.

This has ended up as bit of a lecture and a rant, so I'm just going to leave it here for now.

PackagedCTitleBar.zip

This is a project that I did see the issue in though.

DarranRowe avatar Oct 09 '22 11:10 DarranRowe

AppWindowTitleBar.PreferredHeightOption allows you to extend it. But to be honest, the Windows design guidelines state that title bars should either be 32 or 48 pixels. This class seems to conform to that. If you are looking for a general purpose API, your best option is still using DWM.

SetDragRectangles allows you to manually define the height of the drag regions.

dongle-the-gadget avatar Oct 12 '22 12:10 dongle-the-gadget

I have the same problem in version 1.2.220930.4-preview2. I did not set up a custom drag and drop area, but simply added the code: AppWindowTitleBar.ExtendsContentIntoTitleBar = true.

On Windows 11, it behaves all right. On Windows 10, I have to click the "maximize" button twice before I can drag the window properly.

Extra2001 avatar Oct 15 '22 13:10 Extra2001

I also had the same proble in 1.2.220930 preview 2 in a WinUI 3 application. I followed instructions for Windows App SDK from documentation. It worked well for Windows 11. But above mentioned issue appeared in Windows 10 while all other parts of my customized title bar worked fine.

AppWindowTitleBar.IsCustomizationSupported() did return true for Windows 10 (I had 19044) as documentation stated and ExtendsContentIntoTitleBar was set to true. I did not explicitly call "SetTitleBar" which is another way of customizing WinUI 3 title bar according to the "WinUI3 part" from documentation. This is because the "WinUI3 part" does not allow customized drag rectangles for interactive controls.

However, I found a work around mentioned by @himesamanoyume in https://github.com/DGP-Studio/Snap.Hutao/issues/124#issuecomment-1297820058 where you could manually adjust the window's height, then you would be able to drag the window. But, the issue persists if title bar's size is changed (i.e. when the window's width is changed, AppTitleBar_SizeChanged is fired to call SetDragRegionForCustomTitleBar and re-set drag rectangles again).

Edit: Work around in your code: It turns out that you could also make it work by setting the same window size in code-behind. You can do this by adding appWindow.ResizeClient(appWindow.ClientSize) after you call appWindow.TitleBar.SetDragRectangles(dragRects). The code from documentation becomes

private void SetDragRegionForCustomTitleBar(AppWindow appWindow)
{
    // Check to see if customization is supported.
    // Currently only supported on Windows 11.
    if (AppWindowTitleBar.IsCustomizationSupported()
        && appWindow.TitleBar.ExtendsContentIntoTitleBar)
    {
        double scaleAdjustment = GetScaleAdjustment();

        RightPaddingColumn.Width = new GridLength(appWindow.TitleBar.RightInset / scaleAdjustment);
        LeftPaddingColumn.Width = new GridLength(appWindow.TitleBar.LeftInset / scaleAdjustment);

        List<Windows.Graphics.RectInt32> dragRectsList = new();

        Windows.Graphics.RectInt32 dragRectL;
        dragRectL.X = (int)((LeftPaddingColumn.ActualWidth) * scaleAdjustment);
        dragRectL.Y = 0;
        dragRectL.Height = (int)(AppTitleBar.ActualHeight * scaleAdjustment);
        dragRectL.Width = (int)((IconColumn.ActualWidth
                                + TitleColumn.ActualWidth
                                + LeftDragColumn.ActualWidth) * scaleAdjustment);
        dragRectsList.Add(dragRectL);

        Windows.Graphics.RectInt32 dragRectR;
        dragRectR.X = (int)((LeftPaddingColumn.ActualWidth
                            + IconColumn.ActualWidth
                            + TitleTextBlock.ActualWidth
                            + LeftDragColumn.ActualWidth
                            + SearchColumn.ActualWidth) * scaleAdjustment);
        dragRectR.Y = 0;
        dragRectR.Height = (int)(AppTitleBar.ActualHeight * scaleAdjustment);
        dragRectR.Width = (int)(RightDragColumn.ActualWidth * scaleAdjustment);
        dragRectsList.Add(dragRectR);

        Windows.Graphics.RectInt32[] dragRects = dragRectsList.ToArray();

        appWindow.TitleBar.SetDragRectangles(dragRects);
        // add this to set the same window size after every time drag rectangles are set
        appWindow.ResizeClient(appWindow.ClientSize);
    }
}

Shellishack avatar Nov 05 '22 12:11 Shellishack

@Glitterinn I tested your workaround and it works fine. For others who don’t want read too much:

Simply add

SizeInt32 size = appWindow.ClientSize;
size.Height -= (int)(31 * User32.GetDpiForWindow(hwnd));
appWindow.ResizeClient(size);

after your appWindow.TitleBar.SetDragRectangles

* tips: appWindow & hwnd reprensents the same window here.

Lightczx avatar Nov 05 '22 13:11 Lightczx

Update: workaround found.

@Glitterinn After more test,I found the client area bottom part can glich. Bottom part will extend 38px when resizing,and recover after mouse released.

Lightczx avatar Nov 05 '22 14:11 Lightczx

Why do we constantly need to use workarounds? This worked fine in version 1.1.X on Windows 10 and 11.

Now we're sampling 1.2 and using the same code that worked with 1.1.X (1.0.X as well):

MainWindow.ExtendsContentIntoTitleBar = true;
MainWindow.SetTitleBar(titleBar); // Where titlebar is a content control with a stackpanel that contains an image and some textblocks

The main window cannot be dragged nor do any of the caption buttons work.

This is happening in a self contained C# desktop app using WindowsAppSdk 1.2.230217.4 on Windows 10. Haven't bothered to test on Windows 11.

1.2 has fixed numerous problems we were experiencing, but has broken just as many other things. Please can you guys test your stuff before releasing? Please fix this. If this is supposed to be a breaking change then it's ridiculous.

AdriaanLarcai avatar Feb 27 '23 19:02 AdriaanLarcai