After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 777176 - [wayland] gedit killed by protocol error "Invalid anchor rectangle size"
[wayland] gedit killed by protocol error "Invalid anchor rectangle size"
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Wayland
3.22.x
Other Linux
: Normal major
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2017-01-12 14:50 UTC by Olivier Fourdan
Modified: 2017-01-16 13:18 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
WAYLAND_DEBUG=1 (25.47 KB, text/plain)
2017-01-12 14:50 UTC, Olivier Fourdan
  Details
[PATCH] wayland: avoid 0 width/height anchor rectangle (1.49 KB, patch)
2017-01-12 17:22 UTC, Olivier Fourdan
none Details | Review
[PATCH v2] wayland: avoid 0 width/height anchor rectangle (2.25 KB, patch)
2017-01-13 08:24 UTC, Olivier Fourdan
none Details | Review
[PATCH v3] wayland: avoid 0 width/height anchor rectangle (2.78 KB, patch)
2017-01-16 10:32 UTC, Olivier Fourdan
committed Details | Review

Description Olivier Fourdan 2017-01-12 14:50:01 UTC
Created attachment 343368 [details]
WAYLAND_DEBUG=1

Description:

Pressing the "Windows" key in gedit on Wayland leads to a protocol error and all work lost.

How reproducible:

Always

Steps to reproduce

1. Run gedit
2. Press the "Windows" key on the keyboard

Expected result:

Context menu appears

Actual result

gedit vanishes, along with all unsaved work.

Additional data:

Wayland debug logs attached:

[3127670.634]  -> zxdg_positioner_v6@48.set_anchor_rect(226, 49, 0, 19)
...
[3127682.148] wl_display@1.error(nil, 0, "Invalid anchor rectangle size")
Comment 1 Olivier Fourdan 2017-01-12 17:09:31 UTC
gtk+ passes an invalid rect with a width of 0 to set_anchor_rect() which triggers a Wayland protocol error.

That rect comes from pango, from:

->  popup_targets_received() in gtk+/gtk/gtktextview.c
-> gtk_text_view_get_iter_location()
-> gtk_text_layout_get_iter_location()
...
3022   pango_layout_index_to_pos (display->layout, byte_index, &pango_rect);
3023   
3024   rect->x = PANGO_PIXELS (x_offset + pango_rect.x);
3025   rect->y += PANGO_PIXELS (pango_rect.y) + display->top_margin;
3026   rect->width = PANGO_PIXELS (pango_rect.width);
3027   rect->height = PANGO_PIXELS (pango_rect.height);
Comment 2 Olivier Fourdan 2017-01-12 17:22:24 UTC
Created attachment 343383 [details] [review]
[PATCH] wayland: avoid 0 width/height anchor rectangle

Passing a rectable with zero width or height to xdg_shell-v6
set_anchor_rect() will cause a protocol error and terminate the client,
as with gedit when pressing the Win key.

Reason for this is because the rectangle used to set the anchor comes
from gtk_text_layout_get_iter_location() which uses the pango layout
width/height, which can be empty if there is not character at the given
location.

Make sure we don't use 0 as width or height as an anchor rectangle to
avoid the protocol error.
Comment 3 Matthias Clasen 2017-01-12 18:44:38 UTC
Review of attachment 343383 [details] [review]:

Typo in the commit message: "rectable". In principle, the patch looks fine, but I would suggest to reconsider if it is a wise choice to build error conditions like this into the protocol.
Comment 4 Jonas Ådahl 2017-01-13 01:45:36 UTC
Review of attachment 343383 [details] [review]:

Wouldn't this mean we offset the popup by 1 pixel in this case? I.e. if GTK+ wants to position something against 0x0+50+50, we'd now position it at (51,51) if the default move-to-rect rules apply. The problem though is that I can't think of a valid rule that positions the menu against a point|line, as the min size of the anchor rect is as mentioned 1.

So, this particular error condition might be a mistake, and should rather be if its negative size instead, allowing empty anchor rects.
Comment 5 Olivier Fourdan 2017-01-13 07:53:58 UTC
Yes, as you say, xdg-shell v6 positionner definition makes it clear that the rectangle should not be 0:

  https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-shell/xdg-shell-unstable-v6.xml#n115

      For an xdg_positioner object to be considered complete, it must have a
      non-zero size set by set_size, and a non-zero anchor rectangle set by
      set_anchor_rect. Passing an incomplete xdg_positioner object when
      positioning a surface raises an error.

So the same error occurs with weston as well. 

There is a possibility that we can do, though, if the given size is zero, we use 1 as with attachment 343383 [details] [review]  but then compensate by moving the position by 1 pixel in the opposite direction.

Definitely a hack, but that would give the expected result without breaking the existing rules.
Comment 6 Jonas Ådahl 2017-01-13 08:18:51 UTC
(In reply to Olivier Fourdan from comment #5)
> Yes, as you say, xdg-shell v6 positionner definition makes it clear that the
> rectangle should not be 0:
> 
>  
> https://cgit.freedesktop.org/wayland/wayland-protocols/tree/unstable/xdg-
> shell/xdg-shell-unstable-v6.xml#n115
> 
>       For an xdg_positioner object to be considered complete, it must have a
>       non-zero size set by set_size, and a non-zero anchor rectangle set by
>       set_anchor_rect. Passing an incomplete xdg_positioner object when
>       positioning a surface raises an error.
> 
> So the same error occurs with weston as well. 
> 
> There is a possibility that we can do, though, if the given size is zero, we
> use 1 as with attachment 343383 [details] [review] [review]  but then compensate by
> moving the position by 1 pixel in the opposite direction.
> 
> Definitely a hack, but that would give the expected result without breaking
> the existing rules.

The problem with that is that it'd be offset by 2 pixels if it flipped. Then again, if this is supposed to open at the "|" cursor (maybe it should still be a non-empty anchor that it should flip around, i.e. the width of the "|" cursor thing. So, I think the current patch is the best we can do for now, but we should still probably allow empty-size anchor in the next xdg-positioner version.
Comment 7 Olivier Fourdan 2017-01-13 08:24:29 UTC
Created attachment 343414 [details] [review]
[PATCH v2] wayland: avoid 0 width/height anchor rectangle

Passing a rectangle with zero width or height to xdg_shell-v6
set_anchor_rect() will cause a protocol error and terminate the client,
as with gedit when pressing the Win key.

Reason for this is because the rectangle used to set the anchor comes
from gtk_text_layout_get_iter_location() which uses the pango layout
width/height, which can be empty if there is not character at the given
location.

Make sure we don't use 0 as width or height as an anchor rectangle to
avoid the protocol error, and compensate the logical position of the
given rectangle if the size is changed, so that the actual position
remains as expected by the client.
--
v2: Move the trickery to a separate sanitize_anchor_rect() function
    Compensate the position if the size is changed
    Fix typo in commit message
Comment 8 Olivier Fourdan 2017-01-13 08:31:31 UTC
(In reply to Jonas Ådahl from comment #6)
> The problem with that is that it'd be offset by 2 pixels if it flipped. Then
> again, if this is supposed to open at the "|" cursor (maybe it should still
> be a non-empty anchor that it should flip around, i.e. the width of the "|"
> cursor thing.

The flip case is not so obvious to spot to be honest, and much less likely to occur (this is a problem that occurs only when the pango layout is empty, which is not so common, and when the menu needs flipping, which is even less common).

I reckon that attachment 343414 [details] [review] is better for the most general, common case. And tbh, I can't spot a wrong offset even when flipped using the zoom :)
Comment 9 Olivier Fourdan 2017-01-16 08:22:52 UTC
So which one do we push, attachment 343383 [details] [review] (with a fix in the commit message) or attachment 343414 [details] [review] ?
Comment 10 Jonas Ådahl 2017-01-16 08:27:20 UTC
(In reply to Olivier Fourdan from comment #9)
> So which one do we push, attachment 343383 [details] [review] [review] (with a fix in
> the commit message) or attachment 343414 [details] [review] [review] ?

I'd say we should avoid shifting the position. What if the position was at (0,0). xdg-shell doesn't allow positioning against outside of the window. We could do as in the latest patch, but also clamp so that its within the window geometry.
Comment 11 Olivier Fourdan 2017-01-16 10:32:55 UTC
Created attachment 343542 [details] [review]
[PATCH v3] wayland: avoid 0 width/height anchor rectangle

v3: Make sure the anchor rectangle does not extend outside the window
    geometry of the parent surface after adjusting the size and position of
    the anchor rectangle to avoid a protocol error because of 0 width/height.
Comment 12 Jonas Ådahl 2017-01-16 11:31:23 UTC
Review of attachment 343542 [details] [review]:

Looks good to me (with one style nit)

::: gdk/wayland/gdkwindow-wayland.c
@@ +2679,3 @@
+
+  rect->width  = MAX(1, rect->width);
+  rect->height = MAX(1, rect->height);

nit: space between MAX and (
Comment 13 Olivier Fourdan 2017-01-16 13:18:17 UTC
Comment on attachment 343542 [details] [review]
[PATCH v3] wayland: avoid 0 width/height anchor rectangle

attachment 343542 [details] [review] pushed to git branch gtk-3-22 as commit 9a5ffcd - wayland: avoid 0 width/height anchor rectangle

attachment 343542 [details] [review] pushed to git master as commit 4259aba - wayland: avoid 0 width/height anchor rectangle