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 751140 - lots of "pixman_region32_init_rect: Invalid rectangle passed"
lots of "pixman_region32_init_rect: Invalid rectangle passed"
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: .General
3.17.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2015-06-18 07:22 UTC by Christoph Reiter (lazka)
Modified: 2015-06-22 13:27 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
window: Reinstate logic for should_use_csd() (1.01 KB, patch)
2015-06-18 13:51 UTC, Emmanuele Bassi (:ebassi)
committed Details | Review
Fix calculation of edge input window size in case the real window is too small. (6.43 KB, patch)
2015-06-20 11:37 UTC, Christoph Reiter (lazka)
committed Details | Review

Description Christoph Reiter (lazka) 2015-06-18 07:22:39 UTC
Bisected to https://git.gnome.org/browse/gtk+/commit/?id=c5e5ee67490e7e7

#############

#include <gtk/gtk.h>

int main (int argc, char **argv)
{
    GtkWidget *window, *button;
    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    button = gtk_button_new ();
    gtk_container_add (GTK_CONTAINER (window), button);
    gtk_widget_show_all (window);

    return 0;
}

#############

* BUG ***
In pixman_region32_init_rect: Invalid rectangle passed
Set a breakpoint on '_pixman_log_error' to debug

*** BUG ***
In pixman_region32_init_rect: Invalid rectangle passed
Set a breakpoint on '_pixman_log_error' to debug

*** BUG ***
In pixman_region32_init_rect: Invalid rectangle passed
Set a breakpoint on '_pixman_log_error' to debug

*** BUG ***
In pixman_region32_init_rect: Invalid rectangle passed
Set a breakpoint on '_pixman_log_error' to debug
Comment 1 Christoph Reiter (lazka) 2015-06-18 07:50:28 UTC
(since it was asked in IRC) I'm using gnome-shell 3.16.2
Comment 2 Emmanuele Bassi (:ebassi) 2015-06-18 12:03:06 UTC
Can reproduce, but considering that the code example does not deal with client-side decorations, I strongly doubt my commit is related — except as it probably exposes a logic bug that was masked before.
Comment 3 Emmanuele Bassi (:ebassi) 2015-06-18 12:47:46 UTC
The backtrace, for the record:

  • #0 _pixman_log_error
    from /lib64/libpixman-1.so.0
  • #1 pixman_region32_init_rect
    from /lib64/libpixman-1.so.0
  • #2 INT_cairo_region_create_rectangle
    at cairo-region.c line 338
  • #3 recompute_visible_regions_internal
    at gdkwindow.c line 928
  • #4 recompute_visible_regions
    at gdkwindow.c line 1029
  • #5 set_viewable
    at gdkwindow.c line 4847
  • #6 set_viewable
    at gdkwindow.c line 4855
  • #7 _gdk_window_update_viewable
    at gdkwindow.c line 4912
  • #8 _gdk_set_window_state
    at gdkevents.c line 2125
  • #9 gdk_synthesize_window_state
    at gdkevents.c line 2152
  • #10 gdk_window_show_internal
    at gdkwindow.c line 4939
  • #11 gtk_window_map
    at gtkwindow.c line 6136
  • #12 _g_closure_invoke_va
    at gclosure.c line 864
  • #13 g_signal_emit_valist
    at gsignal.c line 3246
  • #14 g_signal_emit
    at gsignal.c line 3393
  • #15 gtk_widget_map
    at gtkwidget.c line 5068
  • #16 gtk_window_show
    at gtkwindow.c line 5988
  • #17 g_closure_invoke
    at gclosure.c line 801
  • #18 signal_emit_unlocked_R
    at gsignal.c line 3511
  • #19 g_signal_emit_valist
    at gsignal.c line 3337
  • #20 g_signal_emit
    at gsignal.c line 3393
  • #21 gtk_widget_show
    at gtkwidget.c line 4874
  • #3 recompute_visible_regions_internal
    at gdkwindow.c line 928
$1 = {x = 46, y = 23, width = -40, height = 10}

I suspect we're still trying to remove something from the allocation even if CSD is not used.
Comment 4 Emmanuele Bassi (:ebassi) 2015-06-18 13:14:00 UTC
So, this is odd:

-  return csd_env == NULL || (strcmp (csd_env, "1") == 0);
+  return (g_strcmp0 (csd_env, "1") == 0);


This change to gtk_window_can_use_csd() fixes the issue — in the sense that we don't get invalid rectangles — but I'm a bit at loss as to why.

g_strcmp0() returns `-(str1 != str2)` if str1 is NULL, because it can be used for sorting, and NULL strings come before non-NULL ones. In this case, we're doing a strict equality, so the two lines above have the same truth value.
Comment 5 Emmanuele Bassi (:ebassi) 2015-06-18 13:46:18 UTC
The issue is that before we were returning FALSE is GTK_CSD was unset, which is not really what we want. The commit in question changed the logic to return TRUE from can_use_csd() if GTK_CSD is unset — which breaks some state down the line.

Fun.
Comment 6 Emmanuele Bassi (:ebassi) 2015-06-18 13:51:33 UTC
Created attachment 305582 [details] [review]
window: Reinstate logic for should_use_csd()

The old should_use_csd() function would return FALSE if the GTK_CSD
environment variable is unset; the change in commit c5e5ee67490e7e7
made it return TRUE if GTK_CSD is unset. This has a cascade effect
on the window size, which causes invalid rectangles to bubble down
to Pixman.
Comment 7 Emmanuele Bassi (:ebassi) 2015-06-18 13:53:49 UTC
Attachment 305582 [details] pushed as f043fd5 - window: Reinstate logic for should_use_csd()
Comment 8 Emmanuele Bassi (:ebassi) 2015-06-18 15:10:32 UTC
And this, obviously, broke CSD because now can_use_csd(), which is used by enable_csd(), returns FALSE when GTK_CSD is unset.

I guess the proper solution is to actually find out *where* we're screwing up the size of the GdkWindow, thus causing invalid rectangles to be submitted to Pixman.
Comment 9 Christoph Reiter (lazka) 2015-06-20 11:37:38 UTC
Created attachment 305739 [details] [review]
Fix calculation of edge input window size in case the real  window is too small.

This error resulted in warnings like
"pixman_region32_init_rect: Invalid rectangle passed"

In case the window is smaller than handle_size * 2 the resulting
edge window got a negative size. Prevent that by limiting the
handle size to half the respective edge length. This also
prevents the corner windows from overlapping in case the window
is too small.
Comment 10 Christoph Reiter (lazka) 2015-06-20 11:40:58 UTC
Side note: this doesn't handle cases where the calculation results in a zero width/height input window, which gdk silently fixes to be 1 pixel width/height windows in gdk_window_move_resize_internal(). The previous code didn't either so I left it that way.
Comment 11 Emmanuele Bassi (:ebassi) 2015-06-22 13:26:23 UTC
Review of attachment 305739 [details] [review]:

Looks good.

I've reverted commit c5e5ee6 because it broke the default size of empty GtkWindows, but this patch catches invalid sizes before we get to Cairo, which is a good thing.