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 694086 - GtkEntry elements need clipping
GtkEntry elements need clipping
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Widget: GtkEntry
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2013-02-18 13:57 UTC by Martin Stransky
Modified: 2013-07-26 12:17 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GtkEntry - gtk_render_background() (5.63 KB, image/png)
2013-02-18 15:12 UTC, Martin Stransky
  Details
GtkEntry - gtk_render_frame() (12.65 KB, image/png)
2013-02-18 15:14 UTC, Martin Stransky
  Details
gtk_draw_insertion_cursor() withnout clipping - fills whole entry (8.57 KB, image/png)
2013-02-18 15:18 UTC, Martin Stransky
  Details
before gtkentry paint (8.98 KB, image/png)
2013-02-21 11:09 UTC, Martin Stransky
  Details
after gtkentry paint (799 bytes, image/png)
2013-02-21 11:10 UTC, Martin Stransky
  Details
testcase (2.19 KB, text/plain)
2013-07-23 09:55 UTC, Martin Stransky
  Details
cairo new path (7.54 KB, patch)
2013-07-24 09:10 UTC, Martin Stransky
committed Details | Review

Description Martin Stransky 2013-02-18 13:57:16 UTC
I see this bug in GTK3 Firefox port on Fedora 18 and Fedora 15.

When GtkEntry elements are drawn by gtk_render_background()/gtk_render_frame(), the background and frame fill whole window area with bg color or draw some artefacts around so I have to set cairo clipping to achieve proper look. Both (gtk_render_background() and gtk_render_frame()) needs the clipping.

I affects gtk_draw_insertion_cursor() too, it fills whole GtkEntry element area without the clipping.

// Extra clipping code for GtkEntry
GdkRectangle clipped_rect = {x, y, width, height};
gdk_cairo_rectangle(cr, &clipped_rect);
cairo_clip(cr);

style = gtk_widget_get_style_context(gEntryWidget);
gtk_render_background(style, cr, x, y, width, height);
gtk_render_frame(style, cr, x, y, width, height);

// Extra clipping code for cursor
gdk_cairo_rectangle(cr, &location);
cairo_clip(cr);

gtk_draw_insertion_cursor(gEntryWidget, cr, &location, TRUE, direction, FALSE);
Comment 1 Martin Stransky 2013-02-18 15:12:43 UTC
Created attachment 236608 [details]
GtkEntry - gtk_render_background()

GtkEntry & gtk_render_background() only - see that the whole window area is filled, tabs which are under the menu are missing.
Comment 2 Martin Stransky 2013-02-18 15:14:57 UTC
Created attachment 236610 [details]
GtkEntry - gtk_render_frame()

GtkEntry & gtk_render_frame() only - see the grey artifacts produced by the second entry box (google search).
Comment 3 Martin Stransky 2013-02-18 15:18:11 UTC
Created attachment 236612 [details]
gtk_draw_insertion_cursor() withnout clipping - fills whole entry
Comment 4 Benjamin Otte (Company) 2013-02-19 16:33:11 UTC
So, after debugging this with Martin it doesn't seem to be a problem in GTK but rather involve buggy code in Firefox's GTK3 drawing routines.

So I'm gonna close this for now.
Comment 5 Martin Stransky 2013-02-21 11:09:46 UTC
Created attachment 237028 [details]
before gtkentry paint
Comment 6 Martin Stransky 2013-02-21 11:10:08 UTC
Created attachment 237029 [details]
after gtkentry paint
Comment 7 Martin Stransky 2013-02-21 11:44:34 UTC
After some debugging it still looks like a bug in the gtk/cairo for me :) See those the two screenshots, before and after gtkentry paint.
Comment 8 Martin Stransky 2013-02-21 12:17:18 UTC
The GtkEntry widget is drawn on 0,0 -> 298,24, there may be some transformations involved. It may be also caused by some bad cairo configuration/setup, but I wonder where to look at.
Comment 9 Martin Stransky 2013-02-21 12:45:51 UTC
Well, the cairo matrix looks okay, it's:
$1 = {xx = 1, yx = 0, xy = 0, yy = 1, x0 = 402,	y0 = 60}
Comment 10 Martin Stransky 2013-02-21 12:46:47 UTC
Ehm, sorry, that's for the first widget. This one is:
$2 = {xx = 1, yx = 0, xy = 0, yy = 1, x0 = 44, y0 = 60}
Comment 11 Martin Stransky 2013-03-20 12:51:54 UTC
I found more widgets which shows similar problems - GtkNotebook, GtkButton in disabled state, GtkEntry and a cursor drawn by gtk_draw_insertion_cursor().
Comment 12 Karl Tomlinson 2013-05-20 09:19:06 UTC
Does this happen even with the default theme?

gtk_draw_insertion_cursor() doesn't actually depend on the theme engine.

That and, in the default theme, render_frame_fill() and _gtk_theming_background_paint_color() limit their drawing, and so don't rely on any clip being already set on the provided cairo_t.

That seems to hint at a cairo bug.
Comment 13 Martin Stransky 2013-07-23 09:55:24 UTC
Created attachment 249879 [details]
testcase

There's a testcase which shows this bug.

gtk_render_background()/gtk_render_frame() does not clear existing cairo path which is used as a clipping area instead of the one, smaller, inside gtk3 element.

When cairo_rectangle() is removed from surface_test() the widgets are rendered correctly.
Comment 14 Benjamin Otte (Company) 2013-07-23 11:52:12 UTC
I'm tempted to close this as NOTABUG because I think it's the responsibility of the caller to make sure the cairo_t is in a proper state when passed to GTK render functions. So there should be no preexisting path, the operator should be OVER, things like that.

Do Mozilla APIs handle that differently?
Comment 15 Martin Stransky 2013-07-23 12:06:50 UTC
(In reply to comment #14)
> I'm tempted to close this as NOTABUG because I think it's the responsibility of
> the caller to make sure the cairo_t is in a proper state when passed to GTK
> render functions. So there should be no preexisting path, the operator should
> be OVER, things like that.

Is that written somewhere in Gtk3 documentation? 

I've got an impression that gtk rendering routines save the current cairo state, draw the widget (set color/shapes and so) and restore the cairo state. When the gtk3 code uses paths I expect the code make sure the path is properly set.

The operators are a different story - if the code does not fiddle with them one can expect they're in correct state and gtk code does not change them either.

> Do Mozilla APIs handle that differently?

How do you mean it?
Comment 16 Benjamin Otte (Company) 2013-07-23 12:35:37 UTC
Paths are not part of the save/restore cycle so one would have to do extra work to get them saved/restored properly. 

In practice I've only ever seen cairo paths used the way GTK does by adding paths only for an immediate operation (clip/fill/stroke) and then clearing the path again before doing anything else with the cairo_t. Which is why I was wondering about Mozilla's use of Cairo and if they treat paths differently.
Comment 17 Martin Stransky 2013-07-23 12:41:48 UTC
Ahh, I see. Well, the "clearing the path again before doing anything else" part is apparently missing in gtk code :) Mozilla just clears cairo path before any rendering, but not after it.
Comment 18 Martin Stransky 2013-07-23 12:44:54 UTC
...so I think the expected workflow is to clear path, create my own and use it. We can apply a workaround in Mozilla for that but my feeling is when I use something I should set it/initialize it properly.
Comment 19 Benjamin Otte (Company) 2013-07-23 14:02:54 UTC
I suppose it doesn't hurt from a performance pov to call cairo_new_path() after cairo_save() in all the gtk_render_*() functions. And it makes people that are new to cairo or that have learned different conventions (like you) not run into weird bugs.

Care to do a patch for that?
Comment 20 Martin Stransky 2013-07-24 08:30:45 UTC
Thanks, will do such patch. Is it enough to do it against gtk+-3.9.8 - the one in Fedora 21?
Comment 21 Benjamin Otte (Company) 2013-07-24 08:36:34 UTC
Yeah, that code probably hasn't changed since 3.8.0.
Comment 22 Martin Stransky 2013-07-24 09:10:58 UTC
Created attachment 250007 [details] [review]
cairo new path
Comment 23 Benjamin Otte (Company) 2013-07-24 10:23:24 UTC
Comment on attachment 250007 [details] [review]
cairo new path

Perfect. I assume you tested it fixes your issue, so feel free to push it.
Comment 24 Martin Stransky 2013-07-26 09:01:21 UTC
Yes, I tested it and it fixes the issue. What do you mean by "feel free to push it"? I don't have any rights here and/or in gtk project.
Comment 25 Matthias Clasen 2013-07-26 11:53:49 UTC
we'll pick it up, no worries
Comment 26 Benjamin Otte (Company) 2013-07-26 11:57:55 UTC
I always think everyone has git access, makes my life way easier because most of the times I'm right.

Pushed your patch, closing this. I don't think we want to backport to 3.8, do we?
Comment 27 Martin Stransky 2013-07-26 12:17:48 UTC
(In reply to comment #26)
> Pushed your patch, closing this. I don't think we want to backport to 3.8, do
> we?

No, I don't think so.