Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UNIX display with scaling != 100% is broken #1927

Closed
keesverruijt opened this issue May 25, 2020 · 49 comments
Closed

UNIX display with scaling != 100% is broken #1927

keesverruijt opened this issue May 25, 2020 · 49 comments

Comments

@keesverruijt
Copy link
Contributor

On Ubuntu 20.04 at least, with GTK3 and display scaling set != 100% the OpenGL display is incorrectly scaled.
At 200% the OpenGL chart display only takes up the bottom left quarter of the screen.

I had the same issue in the radar plugin, and I've fixed it there: opencpn-radar-pi/radar_pi@97064f4
The nicest way is to change the OpenGL viewport size as well as the glOrtho() size and draw fonts at scale as well so you get smooth fonts. An alternative is to only change the viewport size, but this means you're not using the high resolution of the screen so it will look awful.

This is a known issue in wx: https://trac.wxwidgets.org/ticket/17391

opencpn-hidpi

@keesverruijt
Copy link
Contributor Author

BTW the fonts and icons are correct but they are way too small, so these should be scaled as well.

@bdbcat
Copy link
Member

bdbcat commented May 26, 2020

Kees...
Thanks for the report.
I'm afraid this is not going to be fixed for OCPN 5.2 Release. There are a lot of things to track down and test in the gl code. The simple hacks suggested by the wxWidgets issue tracker are not sufficient.
There is always another release....
Dave

@keesverruijt
Copy link
Contributor Author

Yeah, I realize this. I don't think a lot of users have high end Linux laptops with 4K screens :-)

@stelian42
Copy link
Contributor

For the people who might land here: a workaround is to install the GTK2 version: just pick the cosmic build and it will run just fine, with OpenGL + screen scaling and everything (focal does provide wx-GTK2 runtime libraries).

Still, it would be nice to have a GTK3 fix in the next release (and a lot of Linux users have hidpi displays, the Dell XPS 13 is a very popular Linux laptop....).

@Spirarementum
Copy link

First, thanks for you all working on OpenCPN

Got the same problem here. Unfortunately, it makes OpenCPN unusable in my case (along with a few cruising friends of mine). We have just migrated from Windows to Linux and with a power efficient small high-resolution displays that are replacing all those power-hungry low-resolution monitors on desktop and laptops.

Indeed, it would be nice to have a fix for this.

System Info:
Operating System: Kubuntu 20.04
KDE Plasma Version: 5.18.5
KDE Frameworks Version: 5.68.0
Qt Version: 5.12.8
Kernel Version: 5.4.0-77-generic
OS Type: 64-bit
Processors: 4 × Intel® Core™ i5-4570T CPU @ 2.90GHz
OpenGL: 3.0 Mesa 20.2.6

@Spirarementum
Copy link

GTK2
Would this work under Kubuntu ?
I am presently trying to figure this out...any hints would greatly be appreciated.
Thanks

@nohal
Copy link
Collaborator

nohal commented Jun 25, 2021

It would, wxWidgets and OpenCPN are always built against GTK+ on Linux, that you use Kubuntu changes nothing on that.

@Spirarementum
Copy link

Unsure about how to proceed to implement stelian42's workaround (GTK2), I posted a question on AsK Kubuntu (https://askubuntu.com/questions/1348038/how-can-i-revert-from-using-gtk2-to-gtk-3-on-kunbuntu-20-04).

Got back a clear answer that leaves me to question if it's going to work as a temporary workaround?

I would really appreciate more guidance... I am kind of stuck without a working OpenCPN.

p.s.: I have considered disabling OpenGL on OpenCPN but then I lose my radar overlay.

@nohal
Copy link
Collaborator

nohal commented Jun 25, 2021

You got some super overcomplicated, but sure correct, answers there. But the workaround is to simply install OpenCPN package built for an older Ubuntu release, which will pull in all the required dependencies. You don't need to compile anything.

@Spirarementum
Copy link

Thank you for your time and suggestion 'noal'.
This is all relatively new to me so after spending most of the afternoon looking, I could not find on the repository a package built for an older Ubuntu release using GTK2. It's not clear to me how I can find that specific package browsing at the repository at previous version ?

@nohal
Copy link
Collaborator

nohal commented Jun 25, 2021

The packages are in the PPA at https://launchpad.net/~opencpn/+archive/ubuntu/opencpn/+packages

from a quick look the newest "old" enough package currently available there is for Bionic. I don't have any Ubuntu machine to try so can't tell if it is usable on Focal the same way the Cosmic package suggested here was.

@nohal
Copy link
Collaborator

nohal commented Jun 25, 2021

You may also try to start OpenCPN from the terminal using GDK_SCALE=1 opencpn

@Spirarementum
Copy link

Thanks...I am learning alot from our exchange.

GDK_SCALE=1 opencpn is a good temporary workaround.
Still a few issues like the font size of the context menu is very small but I was able to adjust everything else to be readable by increasing the font size.
I sure can live with this till this issue is resolved in a further version.

I will keep the PPA url in my back pocket for now.

1

@bdbcat
Copy link
Member

bdbcat commented Feb 27, 2022

Update...
We have a proposed solution for scaled displays on GTK3/OpenGL available in the OCPN Beta PPA now.
https://launchpad.net/~bdbcat/+archive/ubuntu/opencpn
Please advise results on testing. I have tested on Ubuntu 20.04/arm64 platform.
Thanks
Dave

@stelian42
Copy link
Contributor

stelian42 commented Feb 28, 2022

Is this beta also available from flatpak ? Because the flatpak "beta" channel version is right now 5.6.0-1.ws315+777652e which does not seem to have the proposed solution...

@bdbcat
Copy link
Member

bdbcat commented Mar 1, 2022

Please update flatpak, beta channel. Current version is "5.6.0-2.wx315+777652e"
Tested OK here on aarch64, Ubuntu 20.04
Dave

@stelian42
Copy link
Contributor

Hi Dave, looks fine here as well (Ubuntu 21.10), but only on the internal hidpy panel (with a display scale of 200%).

My laptop (Dell XPS 13) also has a "normal" external HDMI screen (configured with a display scale of 100%), and when I send OpenCPN to this screen, everything in the GUI is too big.

It would be nice to make OpenCPN automatically behave as it should given the current display (not the primary display as it seems to do now).

There are other gtk3 who behave like this (all the gnome standard apps for example). And there are some apps who do not (Chrome, etc)...

@bdbcat
Copy link
Member

bdbcat commented Mar 1, 2022

We are relying on wxWidgets to tell us what display scale is. We use what they tell us, no other choice.
Dell XPS 13 screenshot?

@stelian42
Copy link
Contributor

You want a screenshot of the hidpy panel or external screen ? Or both ?

@bdbcat
Copy link
Member

bdbcat commented Mar 2, 2022

Any screenshot(s) that illustrate the problems you see.

@stelian42
Copy link
Contributor

Here are the two screenshots.

What is important is the physical size of the two displays (the pixel density is different): internal display is a 13" display (3840x2400 pixels, 29x18cm, display scale set to 200%), the external one is a 27" display (2560x1440 pixels, 60x34 cm, display scale set to 100%).

Capture d’écran du 2022-03-02 08-15-25
Capture d’écran du 2022-03-02 08-14-52

@stelian42
Copy link
Contributor

After more thinking, this may be related to the fact that opencpn always starts on the primary display, so it gets the display scale from there, and then it does not modify it when the window is beeing dragged to the external display.

I didn't find a way to force opencpn to start directly on the external display (but some applications do remember the last display they used, maybe part of the window geometry). If this was possible, it may fix the previous issue.

There are also applications which are able to dynamically redraw and change scale when the window is dragged from a display to the other. But maybe this is too difficult to do with OpenCPN and/or wxWidgets....

@bdbcat
Copy link
Member

bdbcat commented Mar 2, 2022

Try a test:

  1. Start O normally on internal display.
  2. Drag O to external monitor.
  3. Settings->Display->Advanced->Disable OpenGL.
  4. External display OK now?
  5. Settings->Display->Advanced->Enable OpenGL.
  6. External display OK now?

Dave

@stelian42
Copy link
Contributor

Nothing changes visually whether I disable or enable OpenGL...

@bdbcat
Copy link
Member

bdbcat commented Mar 2, 2022

Am I understanding correctly that the external display is "clipped" on the left. That is, the screenshot shown is the full screen?

@stelian42
Copy link
Contributor

Sorry, no, it was a full screen capture (which captures both displays) and I manually (and badly) edited it. Here is a better edited one.

The window is being fully shown, there is no issue here. The issue is with (the physical) size of everything (menus, icon, texts, navigational objects etc)

Capture d’écran du 2022-03-02 16-20-55

@bdbcat
Copy link
Member

bdbcat commented Mar 3, 2022

  1. When operating on the external display, check the settings->Display->Advanced->Physical screen width. Is the auto-detected value correct? If not, what happens if you manually change this to the correct value?

@stelian42
Copy link
Contributor

As I said before, I cannot launch O directly on the external display. All I can do is start on the primary screen and then drag the window to the external display.

Anyway, starting on the primary screen (the hidpy laptop panel), the auto-detected value is already wrong: 254 mm detected, about 290 real.

When I drag the O window to the external display, of course this value does not change. I can change it to the real value (600mm), but this doesn't seem to change the size of any GUI or map object. Even after a restart.

Capture d’écran du 2022-03-03 09-20-22

@bdbcat
Copy link
Member

bdbcat commented Mar 5, 2022

And what happens if you adjust the scaling sliders in Settings->UI ?

@stelian42
Copy link
Contributor

I updated flatpak beta to the latest version: 5.6.0.wx315+777652e

When launched on my panel, the toolbar on the left has a physical width of 7mm, which is perfect.

I set up the detected screen size to manual to 600 mm, and dragged the window to the external screen.

The width of the toolbar is 20 mm. If I set the GUI scaling slider to -5, the toolbar is still too big: 12mm.

And the dialogs / icons (in the options dialog for example) are huge.

Moreover, icons in the toolbar, and map object as well are badly rendered: they are sort of blurred, like if they were first reduced in size then enlarged...

Finally, a bug with the compass icon (top right), it is too small, both on the panel and the external screen

Capture d’écran du 2022-03-05 21-47-23

Capture d’écran du 2022-03-05 21-47-44

@Spirarementum
Copy link

Update... We have a proposed solution for scaled displays on GTK3/OpenGL available in the OCPN Beta PPA now. https://launchpad.net/~bdbcat/+archive/ubuntu/opencpn Please advise results on testing. I have tested on Ubuntu 20.04/arm64 platform. Thanks Dave

Hi Dave,
Great news...thank you for your efforts.
Testing with Flatpak:
$ flatpak list
Name Application ID Version Branch Installation
Freedesktop Platform org.freedesktop.Platform 20.08.18 20.08 system
Mesa org.freedesktop.Platform.GL.default 21.1.8 20.08 system
Intel org.freedesktop.Platform.VAAPI.Intel 20.08 system
openh264 org.freedesktop.Platform.openh264 2.1.0 2.0 system
Breeze GTK theme org.gtk.Gtk3theme.Breeze 3.22 system
OpenCPN org.opencpn.OpenCPN 5.6.0-3+777652e stable system

System is :
Operating System: Kubuntu 20.04
KDE Plasma Version: 5.18.8
KDE Frameworks Version: 5.68.0
Qt Version: 5.12.8
Kernel Version: 5.4.0-100-generic
OS Type: 64-bit
Processors: 4 × Intel® Core™ i5-4570T CPU @ 2.90GHz
Memory: 15.4 GiB of RAM

My first impressions is that this works much much better with my 4K displays (3840x2160 and 3840x1100) with a display scale set of 100%.

I have set the Desktop FONTS on to 192 dpi...instead of changing the display scale.
Persisting low impact issues:

  1. AIS Target List: Font to small;
  2. Same for the DashBoard Tactics;
  3. Nivico Radar Plugin Menu...font size somehow problematics as the window is not resizing proportionally to the font size that is linked to User Interface Scale Factor slide in Option/User Interface (OCPN need restart)

image

image

Please do let me know if this needs clarification or further testing.

Regards,

Sergio

@Spirarementum
Copy link

"I have set the Desktop FONTS on to 192 dpi...instead of changing the display scale."
To clarify this...setting the FONTS at 192dpi while keeping Display Scale at 100% makes FONTS readable on my small 15.6inch display.

@bdbcat
Copy link
Member

bdbcat commented Mar 9, 2022

Stelian42...
Trying to work out some method to debug this problem. Some ideas:

  1. Is it possible to disable the internal laptop display, and boot/run linux from the external display (@100%) only?

@stelian42
Copy link
Contributor

Hi Dave, I think I found something: in Ubuntu Settings, go to the Screens tab. If I choose the "Primary Screen" to be the internal panel (like before), OpenCPN display is perfect on the internal panel (at 200%), but not on the external monitor (at 100%)

If I choose the Iiyama monitor as the primary screen, OpenCPN display will be perfect on the external monitor (at 100%), but not on the internal panel. (including almost correct screen width detection, etc)

Another thing I've seen: OpenCPN always starts to the leftmost screen. If I modify the configuration to put the external monitor at the left of the internal panel, OpenCPN will launch on the external monitor. Notice however that this will only affect the initial screen, not the actual display of content (which, as said above, is affected by the "primary screen" setting).

Capture d’écran du 2022-03-09 20-58-40

@bdbcat
Copy link
Member

bdbcat commented Mar 9, 2022

So, when you can start on the external monitor, and start OCPN on that monitor at 100%, with the settings->UI->Scale factors set to "0", then what is the physical width of the toolbar?

@stelian42
Copy link
Contributor

Ah, I just found out, in the same Ubuntu Settings -> Display screen, that I can set my desktop to "single screen", and I can choose the internal panel or the external one.

If I choose the internal panel, with all scale factors set to 0, the detected screen width is 254 mm (instead of real 290 mm), and the toolbar physical width is 7 mm.

If I choose the external monitor, the detected screen width is 677 mm (instead of real 696 mm) and the toolbar physical width is 10 mm.

@bdbcat
Copy link
Member

bdbcat commented Mar 9, 2022

OK, I did the math, that seems right for default toolbar width on external monitor. Thus, we can say that the monitor detection and scaling logic works for this display adapter. For your information, at default scaling, the toolbar is 44 pixels wide.

Back to the dual monitor situation, then.
So what we need is to get some signal from the OS that OCPN has been "dragged" onto the external monitor, so that the scaling factors can be reset.
Please do this:

  1. Set up dual monitor system.
  2. Delete file ~/.opencpn/opencpn.log
  3. Start OCPN, drag to external monitor, and then immediately shut down OCPN.
  4. Post your logfile (opencpn.log) here.

What I am trying to determine is how (if at all) OCPN is reacting to being "dragged". Logfile should tell me that.

@stelian42
Copy link
Contributor

There seem to be no reaction when OpenCPN is being dragged to the external monitor. See the logfile attached.

opencpn.log

@stelian42
Copy link
Contributor

The lack of event may be an internal wxWidgets problem.

But I can live without the ability to drag OpenCPN from one monitor to another, as long as I can launch it directly on either one of the displays (without changing my primary screen in the settings, because this obviously affects the entire desktop).

Maybe this is just some multi-monitor geometry setting OpenCPN is not following ?

@bdbcat
Copy link
Member

bdbcat commented Mar 12, 2022

AFICT, wxWidgets has no notion of multi-monitor support. None.

@transmitterdan
Copy link
Collaborator

Check out the wxDisplay class. There you can learn which monitor a window is on. One way to use that is to make a query within a wxWindow move event handler.

But it gets tricky because a window can be on both monitors in many desktop managers.

@transmitterdan
Copy link
Collaborator

This patch will add the number of displays (n_NumDisplays) and the current display (m_CurrentDisplay) to a ChartCanvas object.

diff --git a/include/chcanv.h b/include/chcanv.h
index 0ab4136be..e390cd45c 100644
--- a/include/chcanv.h
+++ b/include/chcanv.h
@@ -35,6 +35,7 @@
 #include <wx/sound.h>
 #include <wx/grid.h>
 #include <wx/wxhtml.h>
+#include <wx/display.h>
 
 #include "chart1.h"  // for enum types
 #include "ocpndc.h"
@@ -390,6 +391,10 @@ public:
   void FreezePiano() { m_pianoFrozen = true; }
   void ThawPiano() { m_pianoFrozen = false; }
 
+  void UpdateDisplayInfo(void);
+  int m_NumDisplays;
+  int m_CurrentDisplay;
+
   // Todo build more accessors
   bool m_bFollow;
   wxCursor *pCursorPencil;
diff --git a/src/chcanv.cpp b/src/chcanv.cpp
index 9eb09aeaa..ff2a37d6e 100755
--- a/src/chcanv.cpp
+++ b/src/chcanv.cpp
@@ -11366,6 +11366,7 @@ bool ChartCanvas::SetCursor(const wxCursor &c) {
 
 void ChartCanvas::Refresh(bool eraseBackground, const wxRect *rect) {
   if (g_bquiting) return;
+  UpdateDisplayInfo();
   //  Keep the mouse position members up to date
   GetCanvasPixPoint(mouse_x, mouse_y, m_cursor_lat, m_cursor_lon);
 
@@ -11418,6 +11419,7 @@ void ChartCanvas::Refresh(bool eraseBackground, const wxRect *rect) {
 }
 
 void ChartCanvas::Update() {
+  UpdateDisplayInfo();
   if (m_glcc && g_bopengl) {
 #ifdef ocpnUSE_GL
     m_glcc->Update();
@@ -11426,6 +11428,12 @@ void ChartCanvas::Update() {
     wxWindow::Update();
 }
 
+void ChartCanvas::UpdateDisplayInfo(void) {
+    m_NumDisplays = wxDisplay::GetCount();
+    m_CurrentDisplay = wxDisplay::GetFromWindow(this);
+    // wxLogDebug(wxString::Format(_T("Canvas focus is on display %d of %d."),m_CurrentDisplay,m_NumDisplays));
+}
+
 void ChartCanvas::DrawEmboss(ocpnDC &dc, emboss_data *pemboss) {
   if (!pemboss) return;
   int x = pemboss->x, y = pemboss->y;

@stelian42
Copy link
Contributor

Nice job @transmitterdan !

However, keep in mind that we need to deal with two different rendering issues here: first, the ChartCanvas and all the other objects rendered by OpenCPN itself (charts, toolbars, compass icon, etc). I'm sure that, based on the patch above, it should be able to make some logic to dynamically resize all those objects based on the current display.

But there is also a second part: the items directly rendered by GTK (main window with its menus, probably others), and I think (but I may be wrong) that wxWidgets should directly handle this, but it obviously does not. I'm not sure this part can be fixed from outside wxWidgets, and this is why being able to force the display to start OpenCPN on is important, because on start wxWidgets/GTK behaves correctly.

@transmitterdan
Copy link
Collaborator

This code can be added to any object that derives from wxWindow. It is up to the application to sense a change in the display each window is on and reconfigure so wxWidgets picks all the proper ratios of items. I don't think one can reasonably expect wxWidgets to do this automagically.

@bdbcat
Copy link
Member

bdbcat commented Mar 12, 2022

Dan/Stelian42...
Thanks for the info. I missed this class entirely. I must have been absent that day....
Anyway, please understand this will be low priority for O562. I do not have the hardware to work the problem, yet. And it is a very specific use case, not often seen. I will see what can be done.
Dave

@stelian42
Copy link
Contributor

Sure, I understand, although the combination on a hidpy laptop panel with an external monitor should be rather common these days...

@transmitterdan
Copy link
Collaborator

Dave,

I have a setup here that can test 2 hi-res displays of different resolution on Arm Pi. I'll do some investigating over the next week or two.

@bdbcat
Copy link
Member

bdbcat commented Mar 12, 2022

Dan...
I may be able to configure the same, on an rPI 4. Fiddling with cables/adapters.

@nohal nohal added this to the OpenCPN 5.10.0 milestone Feb 25, 2024
@bdbcat
Copy link
Member

bdbcat commented Apr 25, 2024

Overtaken by events.
OpenCPN v5.9+ supports linux display scaling in accordance with wxWidgets capabilities.
Closing.

@bdbcat bdbcat closed this as completed Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants