Skip to content

Commit

Permalink
fix(GTK): pointer events in wrong locations using Wayland
Browse files Browse the repository at this point in the history
For GTK applications using Wayland the title bar is rendered by the
window itself and not by the composer. And it seems to me that GTK
counts the title bar as part of the window and uses it to trigger the
window events, leading to erroneous considerations about the size and
location of pointers in the area where it is used to draw the
components.

The fix adds a GtkEventBox in the window, instead of use the window
events we will be based on the events of the GtkEventBox which we can
assure that the GTK will take into account the title bar.

Related-to: #5706
Signed-off-by: Matheus Castello <matheus@castello.eng.br>
  • Loading branch information
microhobby committed Apr 23, 2021
1 parent 05ec549 commit a7b59c0
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 18 deletions.
30 changes: 17 additions & 13 deletions src/Uno.UI.Runtime.Skia.Gtk/GtkCoreWindowExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,23 @@ public void SetPointerCapture()
public GtkCoreWindowExtension(object owner)
{
_owner = (CoreWindow)owner;
_ownerEvents = (ICoreWindowEvents)owner;

GtkHost.Window.AddEvents((int)RequestedEvents);

GtkHost.Window.EnterNotifyEvent += OnWindowEnterEvent;
GtkHost.Window.LeaveNotifyEvent += OnWindowLeaveEvent;
GtkHost.Window.ButtonPressEvent += OnWindowButtonPressEvent;
GtkHost.Window.ButtonReleaseEvent += OnWindowButtonReleaseEvent;
GtkHost.Window.MotionNotifyEvent += OnWindowMotionEvent;
GtkHost.Window.ScrollEvent += OnWindowScrollEvent;
GtkHost.Window.TouchEvent += OnWindowTouchEvent;
GtkHost.Window.ProximityInEvent += OnWindowProximityInEvent;
GtkHost.Window.ProximityOutEvent += OnWindowProximityOutEvent;
_ownerEvents = (ICoreWindowEvents)owner;

// even though we are not going to use events directly in the window here maintain the masks
GtkHost.Window.AddEvents((int)RequestedEvents);
// add masks for the GtkEventBox
GtkHost.EventBox.AddEvents((int)RequestedEvents);

// Use GtkEventBox to fix Wayland titlebar events
GtkHost.EventBox.EnterNotifyEvent += OnWindowEnterEvent;
GtkHost.EventBox.LeaveNotifyEvent += OnWindowLeaveEvent;
GtkHost.EventBox.ButtonPressEvent += OnWindowButtonPressEvent;
GtkHost.EventBox.ButtonReleaseEvent += OnWindowButtonReleaseEvent;
GtkHost.EventBox.MotionNotifyEvent += OnWindowMotionEvent;
GtkHost.EventBox.ScrollEvent += OnWindowScrollEvent;
GtkHost.EventBox.TouchEvent += OnWindowTouchEvent;
GtkHost.EventBox.ProximityInEvent += OnWindowProximityInEvent;
GtkHost.EventBox.ProximityOutEvent += OnWindowProximityOutEvent;

InitializeKeyboard();
}
Expand Down
12 changes: 8 additions & 4 deletions src/Uno.UI.Runtime.Skia.Gtk/GtkHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ public class GtkHost : ISkiaHost
private readonly string[] _args;
private readonly Func<WUX.Application> _appBuilder;
private static Gtk.Window _window;
private static Gtk.EventBox _eventBox;
private UnoDrawingArea _area;
private Fixed _fix;
private GtkDisplayInformationExtension _displayInformationExtension;

public static Gtk.Window Window => _window;
public static Gtk.EventBox EventBox => _eventBox;

public GtkHost(Func<WUX.Application> appBuilder, string[] args)
{
Expand Down Expand Up @@ -108,13 +110,15 @@ void Dispatch(System.Action d)
WUX.Window.Current.OnNativeSizeChanged(new Windows.Foundation.Size(e.Allocation.Width, e.Allocation.Height));
};

var overlay = new Overlay();

_area = new UnoDrawingArea();
var overlay = new Overlay();

_eventBox = new EventBox();
_area = new UnoDrawingArea();
_fix = new Fixed();
overlay.Add(_area);
overlay.AddOverlay(_fix);
_window.Add(overlay);
_eventBox.Add(overlay);
_window.Add(_eventBox);

/* avoids double invokes at window level */
_area.AddEvents((int)GtkCoreWindowExtension.RequestedEvents);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public TextBoxViewExtension(TextBoxView owner, GtkWindow window)

private Fixed GetWindowTextInputLayer()
{
var overlay = (Overlay)_window.Child;
// now we have the GtkEventBox
var overlay = (Overlay)((EventBox) _window.Child).Child;
return overlay.Children.OfType<Fixed>().First();
}

Expand Down

0 comments on commit a7b59c0

Please sign in to comment.