Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The control buttons and shadow of a window with custom title bar is so weird #7131

Closed
1 of 2 tasks
hez2010 opened this issue May 21, 2022 · 12 comments
Closed
1 of 2 tasks
Labels
area-TitleBar Issues related to custom window title bars. bug Something isn't working product-winui3 WinUI 3 issues team-Reach Issue for the Reach team

Comments

@hez2010
Copy link

hez2010 commented May 21, 2022

Describe the bug

This is how a window with default system title bar looks like:

image

This is how a window with ExtendsContentIntoTitleBar=true looks like:

image

You can observe that the size (and the shape) of control buttons is not consistent:

image

Also, the depth of shadow of the window is not identical:

image

Steps to reproduce the bug

  1. Create a new blank WinUI 3 app with WASDK 1.1-preview3
  2. Set ExtendsContentIntoTitleBar to true

Expected behavior

The control buttons as well as shadow of the window should be identical both with system title bar and custom title bar.

NuGet package version

WinUI 3 - Windows App SDK 1.1 Preview 3: 1.1.0-preview3

Windows app type

  • UWP
  • Win32

Device form factor

Desktop

Windows version

Windows Insider Build (22621)

@hez2010 hez2010 added the bug Something isn't working label May 21, 2022
@ghost ghost added the needs-triage Issue needs to be triaged by the area owners label May 21, 2022
@ojhad ojhad added team-Reach Issue for the Reach team product-winui3 WinUI 3 issues area-TitleBar Issues related to custom window title bars. and removed needs-triage Issue needs to be triaged by the area owners labels Jun 2, 2022
@riverar
Copy link
Contributor

riverar commented Jun 20, 2022

This still reproduces in Windows App SDK 1.1.1. Only difference between the two windows above is ExtendsContentIntoTitleBar = true

Ping @rkarman

@rkarman
Copy link

rkarman commented Jun 29, 2022

Thanks for the ping here @riverar, I was not aware of this issue being logged.

@marb2000 / @MikeHillberg can one of you move this issue over to WinAppSDK so we can assign the proper owners and track this with the windowing team?

@sigmarsson
Copy link

  1. I witness the same with 1.1.4 :

image

  1. Furthermore the caption buttons receive only double mouse clicks and all three buttons operate as Max/Unmax the window.

  2. Furthermore I associate a TeextBlock to the title bar but never appears on the extended title bar area :

image

@ritt-app
Copy link

ritt-app commented Dec 2, 2022

Same behaviour observed for Windows App SDK 1.2.221116.1

@riverar
Copy link
Contributor

riverar commented Dec 2, 2022

@MikeHillberg @jonwis Can you assist here with a move to WAS repo?

@MikeHillberg
Copy link
Contributor

I think we're in the right place; this looks like Window.ExtendsContentIntoTitleBar.

@bpulliam

@RGarrido03
Copy link

Unfortunately this isn’t solved yet in the latest WinAppSDK version.
However, there must be some trick: the latest Phone Link doesn’t suffer from this bug, yet the WinUI 3 Controls app does. Both are made with WinAppSDK & WinUI 3, of course.

@sigmarsson
Copy link

Ensure this is invoked after you .Activate() your window :

(stumbled over this in WinUI Git Hub example)

internal class Win32Ex
{
    private const int WAINACTIVE = 0x00;
    private const int WAACTIVE = 0x01;
    private const int WMACTIVATE = 0x0006;

    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

    public static void UpdateTitleBar(UIElement shell)
    {
        if (shell is FrameworkElement frameworkElement)
        {
            UpdateTitleBar(frameworkElement.RequestedTheme);
        }
        else
        {
            throw new ArgumentException($"Unable to update application title bar: {shell.GetType()}");
        }
    }

    public static void UpdateTitleBar(ElementTheme theme)
    {
        if (App.Window.ExtendsContentIntoTitleBar)
        {
            if (theme != ElementTheme.Default)
            {
                Application.Current.Resources["WindowCaptionForeground"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Colors.White),
                    ElementTheme.Light => new SolidColorBrush(Colors.Black),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionForegroundDisabled"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x66, 0xFF, 0xFF, 0xFF)),
                    ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x66, 0x00, 0x00, 0x00)),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonBackgroundPointerOver"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x33, 0xFF, 0xFF, 0xFF)),
                    ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x33, 0x00, 0x00, 0x00)),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonBackgroundPressed"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x66, 0xFF, 0xFF, 0xFF)),
                    ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x66, 0x00, 0x00, 0x00)),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonStrokePointerOver"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Colors.White),
                    ElementTheme.Light => new SolidColorBrush(Colors.Black),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonStrokePressed"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Colors.White),
                    ElementTheme.Light => new SolidColorBrush(Colors.Black),
                    _ => new SolidColorBrush(Colors.Transparent)
                };
            }

            Application.Current.Resources["WindowCaptionBackground"] = new SolidColorBrush(Colors.Transparent);
            Application.Current.Resources["WindowCaptionBackgroundDisabled"] = new SolidColorBrush(Colors.Transparent);

            var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.Window);

            if (hwnd == GetActiveWindow())
            {
                SendMessage(hwnd, WMACTIVATE, WAINACTIVE, IntPtr.Zero);
                SendMessage(hwnd, WMACTIVATE, WAACTIVE, IntPtr.Zero);
            }
            else
            {
                SendMessage(hwnd, WMACTIVATE, WAACTIVE, IntPtr.Zero);
                SendMessage(hwnd, WMACTIVATE, WAINACTIVE, IntPtr.Zero);
            }
        }
    }
}

@RGarrido03
Copy link

Ensure this is invoked after you .Activate() your window :

(stumbled over this in WinUI Git Hub example)

internal class Win32Ex
{
    private const int WAINACTIVE = 0x00;
    private const int WAACTIVE = 0x01;
    private const int WMACTIVATE = 0x0006;

    [DllImport("user32.dll")]
    private static extern IntPtr GetActiveWindow();

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

    public static void UpdateTitleBar(UIElement shell)
    {
        if (shell is FrameworkElement frameworkElement)
        {
            UpdateTitleBar(frameworkElement.RequestedTheme);
        }
        else
        {
            throw new ArgumentException($"Unable to update application title bar: {shell.GetType()}");
        }
    }

    public static void UpdateTitleBar(ElementTheme theme)
    {
        if (App.Window.ExtendsContentIntoTitleBar)
        {
            if (theme != ElementTheme.Default)
            {
                Application.Current.Resources["WindowCaptionForeground"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Colors.White),
                    ElementTheme.Light => new SolidColorBrush(Colors.Black),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionForegroundDisabled"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x66, 0xFF, 0xFF, 0xFF)),
                    ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x66, 0x00, 0x00, 0x00)),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonBackgroundPointerOver"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x33, 0xFF, 0xFF, 0xFF)),
                    ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x33, 0x00, 0x00, 0x00)),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonBackgroundPressed"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Color.FromArgb(0x66, 0xFF, 0xFF, 0xFF)),
                    ElementTheme.Light => new SolidColorBrush(Color.FromArgb(0x66, 0x00, 0x00, 0x00)),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonStrokePointerOver"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Colors.White),
                    ElementTheme.Light => new SolidColorBrush(Colors.Black),
                    _ => new SolidColorBrush(Colors.Transparent)
                };

                Application.Current.Resources["WindowCaptionButtonStrokePressed"] = theme switch
                {
                    ElementTheme.Dark => new SolidColorBrush(Colors.White),
                    ElementTheme.Light => new SolidColorBrush(Colors.Black),
                    _ => new SolidColorBrush(Colors.Transparent)
                };
            }

            Application.Current.Resources["WindowCaptionBackground"] = new SolidColorBrush(Colors.Transparent);
            Application.Current.Resources["WindowCaptionBackgroundDisabled"] = new SolidColorBrush(Colors.Transparent);

            var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.Window);

            if (hwnd == GetActiveWindow())
            {
                SendMessage(hwnd, WMACTIVATE, WAINACTIVE, IntPtr.Zero);
                SendMessage(hwnd, WMACTIVATE, WAACTIVE, IntPtr.Zero);
            }
            else
            {
                SendMessage(hwnd, WMACTIVATE, WAACTIVE, IntPtr.Zero);
                SendMessage(hwnd, WMACTIVATE, WAINACTIVE, IntPtr.Zero);
            }
        }
    }
}

Thank you very much!! I’ll try that later today :)

@vanduyquang100
Copy link

The problem is still not fixed yet.
But using Window.AppWindow.TitleBar.ExtendsContentIntoTitleBar = true; would give the expected result.

@hez2010
Copy link
Author

hez2010 commented Oct 19, 2023

BTW in WASDK 1.4, the control buttons issue has been fixed.

@pratikone
Copy link
Contributor

closing as fixed in winappsdk 1.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-TitleBar Issues related to custom window title bars. bug Something isn't working product-winui3 WinUI 3 issues team-Reach Issue for the Reach team
Projects
None yet
Development

No branches or pull requests

10 participants