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 731792 - Fix the current desktop preview for HiDpi displays
Fix the current desktop preview for HiDpi displays
Status: RESOLVED OBSOLETE
Product: gnome-control-center
Classification: Core
Component: Background
3.12.x
Other All
: Normal normal
: ---
Assigned To: Debarshi Ray
Control-Center Maintainers
Depends on: 731738
Blocks:
 
 
Reported: 2014-06-17 17:01 UTC by Debarshi Ray
Modified: 2021-06-09 16:34 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
background: Remove unnecessary calculations (1.28 KB, patch)
2014-06-17 17:02 UTC, Debarshi Ray
needs-work Details | Review
background: Fix the current desktop preview for HiDpi displays (3.75 KB, patch)
2014-06-17 17:03 UTC, Debarshi Ray
needs-work Details | Review
Screenshot of bug (490.50 KB, image/png)
2014-06-17 17:06 UTC, Debarshi Ray
  Details
background: Fix the current desktop preview for HiDpi displays (3.77 KB, patch)
2014-06-18 09:52 UTC, Debarshi Ray
reviewed Details | Review
background: Explain why the optimization might be skipped on HiDpi (1.15 KB, patch)
2014-06-18 12:19 UTC, Debarshi Ray
needs-work Details | Review
background: Remove unnecessary calculations (1.45 KB, patch)
2014-06-18 17:49 UTC, Debarshi Ray
needs-work Details | Review
background: Fix the current desktop preview for HiDpi displays (3.92 KB, patch)
2014-06-18 18:22 UTC, Debarshi Ray
needs-work Details | Review

Description Debarshi Ray 2014-06-17 17:01:27 UTC
Apart from the issue mentioned in bug 731738 , we should generate higher resolution images and consider the scale factor in our calculations when doing so.
Comment 1 Debarshi Ray 2014-06-17 17:02:56 UTC
Created attachment 278613 [details] [review]
background: Remove unnecessary calculations
Comment 2 Debarshi Ray 2014-06-17 17:03:24 UTC
Created attachment 278614 [details] [review]
background: Fix the current desktop preview for HiDpi displays
Comment 3 Debarshi Ray 2014-06-17 17:06:41 UTC
Created attachment 278615 [details]
Screenshot of bug

Notice how the wallpaper is overlapping half the height of the top panel, which has itself lost half its width.
Comment 4 Bastien Nocera 2014-06-17 17:53:23 UTC
Review of attachment 278613 [details] [review]:

Because you want to capture the primary screen, not screen 0.
Comment 5 Bastien Nocera 2014-06-17 17:54:58 UTC
Review of attachment 278614 [details] [review]:

This will need testing with a dual screen setup, with the primary screen being the second one from the left.

::: panels/background/cc-background-panel.c
@@ +227,3 @@
 
+  scale_factor = gtk_widget_get_scale_factor (widget);
+  preview_width *= 2;

Huh, * scale_factor.
Comment 6 Debarshi Ray 2014-06-18 09:52:07 UTC
Created attachment 278664 [details] [review]
background: Fix the current desktop preview for HiDpi displays
Comment 7 Debarshi Ray 2014-06-18 11:09:01 UTC
(In reply to comment #4)
> Review of attachment 278613 [details] [review]:
> 
> Because you want to capture the primary screen, not screen 0.

Umm... how is that relevant? :)

This is not about capturing the primary monitor. We have already done that. It is about trying to remove the work area from the screenshot of the primary monitor.

As mentioned in the commit message, capture_rect's (x, y) is always the same as monitor_rect's (x, y), and I can't think of a logical reason for it not to be. What can be different is the height component of capture_rect and monitor_rect.
Comment 8 Debarshi Ray 2014-06-18 11:11:53 UTC
(In reply to comment #5)
> Review of attachment 278614 [details] [review]:
> 
> This will need testing with a dual screen setup, with the primary screen being
> the second one from the left.

That works.

Irrespective of these patches, the code is broken when one of the monitors is rotated or if the secondary is above the primary. I look into those in a separate bug.

> ::: panels/background/cc-background-panel.c
> @@ +227,3 @@
> 
> +  scale_factor = gtk_widget_get_scale_factor (widget);
> +  preview_width *= 2;
> 
> Huh, * scale_factor.

Oops, sorry about that. Fixed.
Comment 9 Debarshi Ray 2014-06-18 11:17:01 UTC
(In reply to comment #8)
> (In reply to comment #5)
> > Review of attachment 278614 [details] [review] [details]:
> > 
> > This will need testing with a dual screen setup, with the primary screen being
> > the second one from the left.
> 
> That works.
> 
> Irrespective of these patches, the code is broken when one of the monitors is
> rotated or if the secondary is above the primary. I look into those in a
> separate bug.

Forgot to mention that I tested the multi-monitor setup on LoDpi. I have to find a connector to hook this Pixel up to my monitor.
Comment 10 Bastien Nocera 2014-06-18 11:25:11 UTC
(In reply to comment #8)
> (In reply to comment #5)
> > Review of attachment 278614 [details] [review] [details]:
> > 
> > This will need testing with a dual screen setup, with the primary screen being
> > the second one from the left.
> 
> That works.
> 
> Irrespective of these patches, the code is broken when one of the monitors is
> rotated or if the secondary is above the primary. I look into those in a
> separate bug.

That's actually something that works right now and that you're regressing on.(In reply to comment #7)
> (In reply to comment #4)
> > Review of attachment 278613 [details] [review] [details]:
> > 
> > Because you want to capture the primary screen, not screen 0.
> 
> Umm... how is that relevant? :)
> 
> This is not about capturing the primary monitor. We have already done that. It
> is about trying to remove the work area from the screenshot of the primary
> monitor.
> 
> As mentioned in the commit message, capture_rect's (x, y) is always the same as
> monitor_rect's (x, y), and I can't think of a logical reason for it not to be.
> What can be different is the height component of capture_rect and monitor_rect.

The capture_rect won't be at the same if there's a panel bar at the bottom (as in classic) or a dock on either side of the screen (see calculate_contiguous_workarea())
Comment 11 Debarshi Ray 2014-06-18 11:39:38 UTC
> > > This will need testing with a dual screen setup, with the primary screen being
> > > the second one from the left.
> > 
> > That works.
> > 
> > Irrespective of these patches, the code is broken when one of the monitors is
> > rotated or if the secondary is above the primary. I look into those in a
> > separate bug.
> 
> That's actually something that works right now and that you're regressing
> on.

What makes you say so? As someone who uses an L-shaped setup everyday, I can see that it does not work right now for these setups.

> The capture_rect won't be at the same if there's a panel bar at the bottom (as
> in classic) or a dock on either side of the screen

Ok, and how does that affect the x and y of capture_rect? 

> (see
> calculate_contiguous_workarea())

How is the x and y of capture_rect going to be different from monitor_rect's in this code:

  if (data->workarea_rect.x != data->monitor_rect.x)
    return FALSE;
  if ((data->workarea_rect.y + data->workarea_rect.height) != (data->monitor_rect.y + data->monitor_rect.height))
    return FALSE;

  data->capture_rect.x = data->monitor_rect.x;
  data->capture_rect.width = data->monitor_rect.width;
  data->capture_rect.y = data->monitor_rect.y;
  data->capture_rect.height = data->monitor_rect.height - data->workarea_rect.height;
Comment 12 Debarshi Ray 2014-06-18 12:19:57 UTC
Created attachment 278672 [details] [review]
background: Explain why the optimization might be skipped on HiDpi

I don't know if it is worth trying to be clever and second guess the rounding error. It does not look too slow without the optimization.
Comment 13 Bastien Nocera 2014-06-18 13:25:04 UTC
Review of attachment 278613 [details] [review]:

> I can't think of a reason why we would place the screenshot anywhere
> other than (0, 0). Moreover, capture_rect.[xy] is always the same as
> monitor_rect.[xy].

This needs a better explanation. Explain what values are assigned to each of the 2 sets of coordinates, and in which functions.
Comment 14 Bastien Nocera 2014-06-18 13:53:46 UTC
Review of attachment 278664 [details] [review]:

::: panels/background/cc-background-panel.c
@@ +284,3 @@
+
+  widget = WID ("background-desktop-drawingarea");
+  scale_factor = gtk_widget_get_scale_factor (widget);

That seems wrong, at least for Wayland which can have scale factors be different values on different monitors. So if the Settings window is on a different screen from the primary screen (on which the top bar is) then the scale factors would be different.

The gnome-shell screenshot API should work in absolute pixels, and we shouldn't need to scale anything other than the default thumbnail size (which you're doing above).

Or did I misread this code?
Comment 15 Debarshi Ray 2014-06-18 17:49:00 UTC
Created attachment 278706 [details] [review]
background: Remove unnecessary calculations

Improve the commit message.
Comment 16 Debarshi Ray 2014-06-18 18:22:27 UTC
Created attachment 278709 [details] [review]
background: Fix the current desktop preview for HiDpi displays
Comment 17 Debarshi Ray 2014-06-18 18:45:30 UTC
(In reply to comment #14)
> Review of attachment 278664 [details] [review]:
> 
> ::: panels/background/cc-background-panel.c
> @@ +284,3 @@
> +
> +  widget = WID ("background-desktop-drawingarea");
> +  scale_factor = gtk_widget_get_scale_factor (widget);
> 
> That seems wrong, at least for Wayland which can have scale factors be
> different values on different monitors. So if the Settings window is on a
> different screen from the primary screen (on which the top bar is) then the
> scale factors would be different.

Good point. I have fixed this now using gdk_screen_get_monitor_scale_factor with the primary monitor. I have not tested it yet on a actual multi-monitor setup because I don't have the cables at the moment.

> The gnome-shell screenshot API should work in absolute pixels, and we shouldn't
> need to scale anything other than the default thumbnail size (which you're
> doing above).

There are a couple of things here:

1. In on_screenshot_finished we have a pixbuf that is a screenshot of the primary monitor. We operate on it with cairo to remove the workarea. Since we are dealing with a GdkPixbuf which is unaware of the scale factor and has raw pixels, we can not use monitor_rect and workarea_rect on it because those values came from GDK and have the unscaled values. So we have to take care of the scale factor of the primary monitor ourselves.

2. Then there is the issue of what values the gnome-shell screenshot API takes. Although related, I don't think this affects (1) because we need the scaled values there anyway. In bug 731738 I changed gnome-shell to take unscaled values. I think that it is better than asking every user (eg., gnome-screenshot) of this API to deal with scaling the GDK values themselves. As you pointed out, this scaling can be tricky on LoDpi + HiDpi setups.
Comment 18 Debarshi Ray 2014-06-18 18:46:05 UTC
(In reply to comment #14)
> Review of attachment 278664 [details] [review]:
> 
> ::: panels/background/cc-background-panel.c
> @@ +284,3 @@
> +
> +  widget = WID ("background-desktop-drawingarea");
> +  scale_factor = gtk_widget_get_scale_factor (widget);
> 
> That seems wrong, at least for Wayland which can have scale factors be
> different values on different monitors. So if the Settings window is on a
> different screen from the primary screen (on which the top bar is) then the
> scale factors would be different.

Good point. I have fixed this now using gdk_screen_get_monitor_scale_factor with the primary monitor. I have not tested it yet on a actual multi-monitor setup because I don't have the cables at the moment.

> The gnome-shell screenshot API should work in absolute pixels, and we shouldn't
> need to scale anything other than the default thumbnail size (which you're
> doing above).

There are a couple of things here:

1. In on_screenshot_finished we have a pixbuf that is a screenshot of the primary monitor. We operate on it with cairo to remove the workarea. Since we are dealing with a GdkPixbuf which is unaware of the scale factor and has raw pixels, we can not use monitor_rect and workarea_rect on it because those values came from GDK and have the unscaled values. So we have to take care of the scale factor of the primary monitor ourselves.

2. Then there is the issue of what values the gnome-shell screenshot API takes. Although related, I don't think this affects (1) because we need the scaled values there anyway. In bug 731738 I changed gnome-shell to take unscaled values. I think that it is better than asking every user (eg., gnome-screenshot) of this API to deal with scaling the GDK values themselves. As you pointed out, this scaling can be tricky on LoDpi + HiDpi setups.
Comment 19 Bastien Nocera 2014-07-01 13:56:39 UTC
(In reply to comment #18)
<snip>
> There are a couple of things here:
> 
> 1. In on_screenshot_finished we have a pixbuf that is a screenshot of the
> primary monitor. We operate on it with cairo to remove the workarea. Since we
> are dealing with a GdkPixbuf which is unaware of the scale factor and has raw
> pixels, we can not use monitor_rect and workarea_rect on it because those
> values came from GDK and have the unscaled values. So we have to take care of
> the scale factor of the primary monitor ourselves.

The problem isn't that GDK doesn't scale those values. That's not what it should be doing. The problem is that gnome-shell doesn't export the right values (it exports the unscaled values instead of the scaled ones).

> 2. Then there is the issue of what values the gnome-shell screenshot API takes.
> Although related, I don't think this affects (1) because we need the scaled
> values there anyway. In bug 731738 I changed gnome-shell to take unscaled
> values. I think that it is better than asking every user (eg.,
> gnome-screenshot) of this API to deal with scaling the GDK values themselves.
> As you pointed out, this scaling can be tricky on LoDpi + HiDpi setups.

GDK's workarea is in pixels, everything should be in pixels. Whether or not there is a scaling factor, if the top bar take 30 pixels instead of 15, we should export 30 pixels as being its height. How gnome-shell scales text and widgets is irrelevant here.
Comment 20 Debarshi Ray 2014-07-01 14:16:18 UTC
(In reply to comment #19)
> GDK's workarea is in pixels

GDK's workarea is not in pixels.
Comment 21 Debarshi Ray 2014-07-01 14:24:53 UTC
(In reply to comment #19)
> (In reply to comment #18)
> <snip>
> > There are a couple of things here:
> > 
> > 1. In on_screenshot_finished we have a pixbuf that is a screenshot of the
> > primary monitor. We operate on it with cairo to remove the workarea. Since we
> > are dealing with a GdkPixbuf which is unaware of the scale factor and has raw
> > pixels, we can not use monitor_rect and workarea_rect on it because those
> > values came from GDK and have the unscaled values. So we have to take care of
> > the scale factor of the primary monitor ourselves.
> 
> The problem isn't that GDK doesn't scale those values. That's not what it
> should be doing. The problem is that gnome-shell doesn't export the right
> values (it exports the unscaled values instead of the scaled ones).

Sorry, this makes no sense to me. Why would gnome-shell export anything? It gives us a screenshot as a GdkPixbuf, and we have some values obtained from GDK which are in app pixels, not device pixels.

If we are to operate on this GdkPixbuf to extract the top panel then we have to work in device pixels because GdkPixbuf has no clue about the scaling factor. So somehow we have to convert the app pixel values from GDK to device pixel values.
Comment 22 Bastien Nocera 2014-07-01 14:32:25 UTC
(In reply to comment #21)
> (In reply to comment #19)
> > (In reply to comment #18)
> > <snip>
> > > There are a couple of things here:
> > > 
> > > 1. In on_screenshot_finished we have a pixbuf that is a screenshot of the
> > > primary monitor. We operate on it with cairo to remove the workarea. Since we
> > > are dealing with a GdkPixbuf which is unaware of the scale factor and has raw
> > > pixels, we can not use monitor_rect and workarea_rect on it because those
> > > values came from GDK and have the unscaled values. So we have to take care of
> > > the scale factor of the primary monitor ourselves.
> > 
> > The problem isn't that GDK doesn't scale those values. That's not what it
> > should be doing. The problem is that gnome-shell doesn't export the right
> > values (it exports the unscaled values instead of the scaled ones).
> 
> Sorry, this makes no sense to me. Why would gnome-shell export anything?

Because EWMH's "work-area" hint is exported by the window manager. GDK picks it up from the window manager:
http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#idm140130317674416

The values exported by gnome-shell are incorrect.

> It
> gives us a screenshot as a GdkPixbuf, and we have some values obtained from GDK
> which are in app pixels, not device pixels.

It's not in app pixels, it's in "gnome-shell" pixels. If the app isn't scaled by gnome-shell is, then the value will be incorrect. It kind of works because your application happens to have the same scale factor as gnome-shell.

You can verify this by setting the GDK scaling factor to a value that's different from gnome-shell's value, the workarea values come from the window manager and aren't scaled by the scale factor.

> If we are to operate on this GdkPixbuf to extract the top panel then we have to
> work in device pixels because GdkPixbuf has no clue about the scaling factor.
> So somehow we have to convert the app pixel values from GDK to device pixel
> values.
Comment 23 Debarshi Ray 2014-07-01 14:47:02 UTC
(In reply to comment #22)
> Because EWMH's "work-area" hint is exported by the window manager. GDK picks it
> up from the window manager:
> http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#idm140130317674416
> 
> The values exported by gnome-shell are incorrect.

See gdk_x11_screen_get_monitor_geometry:
https://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkscreen-x11.c#n251

commit 525e5cff04f66b87314e91ef408525f02923c14b
Author: Alexander Larsson <alexl@redhat.com>
Date:   Thu Jun 20 11:40:07 2013 +0200

    x11: Initial cut at supporting window scaling for X11
    
    If you set GDK_SCALE=2 in the environment then all windows will be
    scaled by 2. Its not an ideal solution as it doesn't handle
    multi-monitors at different scales, and only affects gtk apps.
    But it is a good starting points and will help a lot on HiDPI
    laptops.
Comment 24 Georges Basile Stavracas Neto 2018-01-18 13:18:00 UTC
None of the three patches could be applied against master.
Comment 25 André Klapper 2021-06-09 16:34:25 UTC
GNOME is going to shut down bugzilla.gnome.org in favor of gitlab.gnome.org.
As part of that, we are mass-closing older open tickets in bugzilla.gnome.org
which have not seen updates for a longer time (resources are unfortunately
quite limited so not every ticket can get handled).

If you can still reproduce the situation described in this ticket in a recent
and supported software version, then please follow
  https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines
and create a new bug report at
  https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/

Thank you for your understanding and your help.