Avalonia
Avalonia copied to clipboard
Make content nonclickable in Transparent Window
In WPF, a Window with AllowsTransparency="True" and a Transparent Background has a special behavior I'm missing in Avalonia: If you click on a fully transparent Area of the Window, the click is not handled by this window and goes "through" it, like there is a hole in it. Is it possible and crossplatform conform to implement this behavior?
My use case is to show a Window/Rectangle with only a red border, at a special position, to use as a "marker"/"hint". Actually, if I set SystemDecorations = SystemDecorations.None and TransparencyLevelHint = WindowTransparencyLevel.Transparent, like described in https://github.com/AvaloniaUI/Avalonia/issues/2306 the window is still clickable.
Probably doable via SetWindowRgn on Win32 and XShape extension on Linux. Not quite sure about macOS
Okay, I've managed to use CombineRgn in combination with SetWindowRgn. This is a working solution. But I've got problems to get native window positions from avalonia window. It seems that the location/size differs a bit, or I have a calculation bug in my code. Is there a best practise to get native screen position and size for the avalonia window?
I've re-checked my code. My calculation is correct, but what I found: Window.Position seems NOT to be the position on the screen! How can I get the avalonia window position/location of the screen?
And how can I convert screen coordinates to avalonia window position values?
Window.Position seems NOT to be the position on the screen
Excuse me, what? Window.Position
is returning the value from IWindowImpl.Position
.
Win32 implementation of that property calls GetWindowRect
and takes the coordinate of the upper-left corner.
Those coordinates are in pixel coordinate space.
Ok, it seems that the position I'm getting is correct, but if I set a position using Window.Position it behaves strange. Sorry, I don't want to be unfair. You all doing a great job. Big thanks. I will retest and check what's exactly the cause of it.
I re-read the documentation of CreateRectRgn and found out that it is working with logical units, and not with pixels. This seem to be the problem. Sorry for complain here.
CreateRectRgn should operate in window coordinate space with (0, 0) being the top-left corner of the window
I actually don't get it to work properly. Every time I do a step forward I have to get one or two back... I have a WPF overlay window, to let the user do some decisions for recording, that is working properly. Now I'm migrating it to avalonia, which is wonderful to work with. But this kind of clipping transparent areas makes me headaches.
In full screen mode, clipping a simple rectangle seem to work, but If I resize the window or change the position it behaves strange. It's like the position is exponental shifted, or scaled by something I didn't get...
I will re-use my old WPF code, until avalonia supports it, or I have another idea.
This workaround using MonoMac works on macOS:
// this = Avalonia.Controls.Window
if (this.PlatformImpl.Handle is IMacOSTopLevelPlatformHandle macosHandle) {
MonoMac.AppKit.NSApplication.Init();
var nsWindow = (MonoMac.AppKit.NSWindow) MonoMac.ObjCRuntime.Runtime.GetNSObject(macosHandle.NSWindow);
nsWindow.IgnoresMouseEvents = true;
}
Is there the same simple code for linux as for macOS?
Is there the same simple code for linux as for macOS?
Or a working solution for Windows?
Is there the same simple code for linux as for macOS?
Or a working solution for Windows?
for windows this will help you https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-nchittest and https://github.com/AvaloniaUI/Avalonia/blob/b00144eacd1a61c4ec7cb7d13aadd94c5f995ba9/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs#L416
Is there the same simple code for linux as for macOS?
Or a working solution for Windows?
for windows this will help you https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-nchittest and
https://github.com/AvaloniaUI/Avalonia/blob/b00144eacd1a61c4ec7cb7d13aadd94c5f995ba9/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs#L416
How can I override WndProc to always return HTTRANSPARENT?
I want to know, too?
The Problem is... to show a rectangle it would be a workaround to use 4 Windows and position them... but the next problem than would be that a window have a fixed minWidth of 50 Pixels Width?! So I would need a workaround for a workaround. I see a lack of feature here.
I have a similar issue, I am porting an application which has a window overlay which shows ingame notifications, using the WPF AllowTransparency=True and SetWindowLong(Handle, GWL_EXSTYLE, Style | WS_EX_TRANSPARENT) every component on the window which is basically the notification toast usercontrol is not clickable, which means that every click is passed to the main game window which is what i'm trying to do with avalonia with no success, I tried adding WS_EX_LAYERED to SetWindowLong but with that the window doesn't appear at all. If someone can explain how to apply this clickthrough property to an avalonia window i'll be very grateful.
Edit: nvm, i was able to do that by using:
SetWindowLong(this.PlatformImpl.Handle.Handle, GWL_EXSTYLE, Style | WS_EX_LAYERED | WS_EX_TRANSPARENT)
SetLayeredWindowAttributes(this.PlatformImpl.Handle.Handle, 0, 255, 0x2);
Edit: nvm, i was able to do that by using:
SetWindowLong(this.PlatformImpl.Handle.Handle, GWL_EXSTYLE, Style | WS_EX_LAYERED | WS_EX_TRANSPARENT) SetLayeredWindowAttributes(this.PlatformImpl.Handle.Handle, 0, 255, 0x2);
BINGO! That's a workaround which resolves it in case of OS Platform is Windows! Big Thanks.
@FG-rgb Do you know if it's possible to make some of the controls clickable? I am also porting a project from WPF to Avalonia and I need to create a transparent Window where the notification buttons are clickable.
@FG-rgb Do you know if it's possible to make some of the controls clickable? I am also porting a project from WPF to Avalonia and I need to create a transparent Window where the notification buttons are clickable.
@Jasonvb You can try the approach described by @kekekeks
@FG-rgb I am searching for a cross platform solution.
By the way, I am thinking of creating a seperate Window (only containing the notification itself) for each of the notifications instead of creating one overlay for all notifications. In my application there could be multiple notifications shown at the same time. Is this a good idea or will I get in trouble with setting multiple notification windows topmost=True?
There shouldn't be any problems, but you obviously will have less control over notifications, if you want controls to visually interact with each other, like animations.
Is there any currently available solution? It seems that MonoMac.AppKit
is no longer functional.