Check if a coordinate is a valid screen coordinate when using multiple desktops
-
My application stores the coordinates of specific dock widgets / dialogues when the application is closed. When starting the application again the widgets / dialogues are move to their previous positions.
In same case it may happen one/multiple monitors were unplugged. Thus I need to check if these stored positions are still valid screen coordinates.
In case you have only one desktop (p. e. Windows 7 support only one desktop) this can be done by checking the coordinates against the geometry of all screens provided by QDestopWidget (qApp->desktop()->availableGeometry(screennumber)).
In case you have Linux, MacOS or Windows 10 you can create multiple 'virtual' desktops. In this case I can only access the first 'virtual' desktop using qApp->desktop(). The other virtual desktops can not be accessed to check screen geometry against the coordinates.
Is there a way to access the geometry off all screens in the other virtual desktops too?
-
But does virtual Desktops have geometry ?
http://doc.qt.io/qt-5/qdesktopwidget.html#screen
http://doc.qt.io/qt-5/qdesktopwidget.html#virtualDesktop-prop
"For virtual desktops, screen() will always return the same widget. The size of the virtual desktop is the size of this desktop widget."- Is there a way to access the geometry off all screens in the other virtual desktops too?
I think screen() returns the complete virtual size.
If I make small Qt app and move around in the new win 10 Desktop things.
It seems to 100% transparent to it. Could be interesting to watch what events are posted. -
@mrjj: screen() does not return the complete virtual size (I already checked that). In terms of Qt a virtual desktop is a desktop created by multiple screens (monitors). Thus you just get the size of the first 'virtual' desktop.
In addition a size of a virtual desktop composed by multiple screens is conceptionally wrong. Imagine you created a virtual desktop using three screens, one screen in the centre, one screen above the centre screen and one screen left of the centre screen. Now think about the size of this 'virtual desktop'. -
@mrjj: screen() does not return the complete virtual size (I already checked that). In terms of Qt a virtual desktop is a desktop created by multiple screens (monitors). Thus you just get the size of the first 'virtual' desktop.
In addition a size of a virtual desktop composed by multiple screens is conceptionally wrong. Imagine you created a virtual desktop using three screens, one screen in the centre, one screen above the centre screen and one screen left of the centre screen. Now think about the size of this 'virtual desktop'.@Hagen said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
In addition a size of a virtual desktop composed by multiple screens is conceptionally wrong. Imagine you created a virtual desktop using three screens, one screen in the centre, one screen above the centre screen and one screen left of the centre screen. Now think about the size of this 'virtual desktop'.
It is not wrong.
http://doc.qt.io/qt-5/qdesktopwidget.html#screen-geometry
Screen Geometry
To obtain the dimensions of a particular screen, call the screenGeometry() function. On some desktop environments, not all of the screen is available for applications to use; for example, an application dock or menu bar may take up some space. Use the availableGeometry() function to obtain the available area for applications.
QDesktopWidget also inherits the QWidget properties, width() and height(), which specify the size of the desktop. However, for desktops with multiple screens, the size of the desktop is the union of all the screen sizes, so width() and height() should not be used for computing the size of a widget to be placed on one of the screens.
On systems that are configured to use the available screens as a single, large virtual desktop, the virtualDesktop property will be set to true. In this case, the widget's size is usually the size of the bounding rectangle of all the screens.
-
@Hagen said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
In addition a size of a virtual desktop composed by multiple screens is conceptionally wrong. Imagine you created a virtual desktop using three screens, one screen in the centre, one screen above the centre screen and one screen left of the centre screen. Now think about the size of this 'virtual desktop'.
It is not wrong.
http://doc.qt.io/qt-5/qdesktopwidget.html#screen-geometry
Screen Geometry
To obtain the dimensions of a particular screen, call the screenGeometry() function. On some desktop environments, not all of the screen is available for applications to use; for example, an application dock or menu bar may take up some space. Use the availableGeometry() function to obtain the available area for applications.
QDesktopWidget also inherits the QWidget properties, width() and height(), which specify the size of the desktop. However, for desktops with multiple screens, the size of the desktop is the union of all the screen sizes, so width() and height() should not be used for computing the size of a widget to be placed on one of the screens.
On systems that are configured to use the available screens as a single, large virtual desktop, the virtualDesktop property will be set to true. In this case, the widget's size is usually the size of the bounding rectangle of all the screens.
Sure one can retrieve the geometry of a specific physical screen. I have three physical screens. But in my case I have 4 virtual desktops each composed of these three screens. So I have 4 times 3 screens.
To make it more clear: Each of my monitors has as size of 1920x1200. The QDesktopWidget spans over these three screens resulting in 5760x1200. If I move my application to my second virtual desktop which is positioned right of the first virtual desktop I acquire a position of p. e. (6000, 300) for my application. This position lies outside of the available geometry of QDesktopWidget. In this case I am unable to check if (6000,300) is a valid screen coordinate because I can only access the first virtual desktop (containing my three physical screens) using QDesktopWidget.
Hope this example makes it more clear. If not I can also provide some screenshots.
-
@Hagen said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
In addition a size of a virtual desktop composed by multiple screens is conceptionally wrong. Imagine you created a virtual desktop using three screens, one screen in the centre, one screen above the centre screen and one screen left of the centre screen. Now think about the size of this 'virtual desktop'.
It is not wrong.
http://doc.qt.io/qt-5/qdesktopwidget.html#screen-geometry
Screen Geometry
To obtain the dimensions of a particular screen, call the screenGeometry() function. On some desktop environments, not all of the screen is available for applications to use; for example, an application dock or menu bar may take up some space. Use the availableGeometry() function to obtain the available area for applications.
QDesktopWidget also inherits the QWidget properties, width() and height(), which specify the size of the desktop. However, for desktops with multiple screens, the size of the desktop is the union of all the screen sizes, so width() and height() should not be used for computing the size of a widget to be placed on one of the screens.
On systems that are configured to use the available screens as a single, large virtual desktop, the virtualDesktop property will be set to true. In this case, the widget's size is usually the size of the bounding rectangle of all the screens.
To make it even more clear:
Look at this image http://doc.qt.io/qt-5/qdesktopwidget.html#screen-geometry.
Now imagine I not only having one virtual desktops. I have four of them.
First Virtual Desktop spans from (0,0) to (5720, 1200)
Second Virtual Desktop spans from (5720,0) to (11440, 1200)
Third Virtual Desktop spans from (0,1200) to (5720, 2400)
Forth Virtual Desktop spans from (5720, 1200) to (11440, 2400)QDesktopWidget contains only geometry information of the first virtual desktop! But I need the geometry information of the others too.
-
To make it even more clear:
Look at this image http://doc.qt.io/qt-5/qdesktopwidget.html#screen-geometry.
Now imagine I not only having one virtual desktops. I have four of them.
First Virtual Desktop spans from (0,0) to (5720, 1200)
Second Virtual Desktop spans from (5720,0) to (11440, 1200)
Third Virtual Desktop spans from (0,1200) to (5720, 2400)
Forth Virtual Desktop spans from (5720, 1200) to (11440, 2400)QDesktopWidget contains only geometry information of the first virtual desktop! But I need the geometry information of the others too.
As I understand it, a virtual desktop will start always from (0,0) and span whatever physical screens you've added, thus all virtual desktops will have the same geometry - (0,0) to (5720, 1200) in your example case. If you need to find out if a point is valid screen position, then I think using
QDesktopWidget::screenGeometry
should give you what you're after (i.e. to implement it yourself). -
As I understand it, a virtual desktop will start always from (0,0) and span whatever physical screens you've added, thus all virtual desktops will have the same geometry - (0,0) to (5720, 1200) in your example case. If you need to find out if a point is valid screen position, then I think using
QDesktopWidget::screenGeometry
should give you what you're after (i.e. to implement it yourself).I already tried it with QDesktopWidget::screenGeometry and QDesktopWidget::availableGeometry ( see my first post). But both routines return (5720, 1200) as largest point. Thus any check against a position greater than this position fails. Thus for my example the point (6000,300) is not valid in terms of QDesktopWidget::screenGeometry. But in fact (6000,300) is a valid desktop coordinate because it is returned by QWidget::pos() of my application.
So does anybody has an other idea to solve this problem for more than one virtual desktop?
-
I already tried it with QDesktopWidget::screenGeometry and QDesktopWidget::availableGeometry ( see my first post). But both routines return (5720, 1200) as largest point. Thus any check against a position greater than this position fails. Thus for my example the point (6000,300) is not valid in terms of QDesktopWidget::screenGeometry. But in fact (6000,300) is a valid desktop coordinate because it is returned by QWidget::pos() of my application.
So does anybody has an other idea to solve this problem for more than one virtual desktop?
@Hagen said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
I already tried it with QDesktopWidget::screenGeometry and QDesktopWidget::availableGeometry ( see my first post).
Your first post mentions nothing about
QDesktopWidget::screenGeometry
, and I've actually tried the function and it works correctly. Here's my test code:#include <QApplication> #include <QDesktopWidget> #include <QDebug> #include <QTimer> int main(int argc, char *argv[]) { QApplication app(argc, argv); QTimer::singleShot(0, [&app] () -> void { QDesktopWidget * desktop = QApplication::desktop(); for (qint32 i = 0, screens = desktop->screenCount(); i < screens; i++) { qDebug() << desktop->screenGeometry(i); } app.quit(); }); return QApplication::exec(); }
Which outputs:
QRect(0,0 1920x1080) QRect(1920,0 1920x1080)
Which is correct, as I'm running 2 1920x1080 monitors side to side.
-
@Hagen said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
I already tried it with QDesktopWidget::screenGeometry and QDesktopWidget::availableGeometry ( see my first post).
Your first post mentions nothing about
QDesktopWidget::screenGeometry
, and I've actually tried the function and it works correctly. Here's my test code:#include <QApplication> #include <QDesktopWidget> #include <QDebug> #include <QTimer> int main(int argc, char *argv[]) { QApplication app(argc, argv); QTimer::singleShot(0, [&app] () -> void { QDesktopWidget * desktop = QApplication::desktop(); for (qint32 i = 0, screens = desktop->screenCount(); i < screens; i++) { qDebug() << desktop->screenGeometry(i); } app.quit(); }); return QApplication::exec(); }
Which outputs:
QRect(0,0 1920x1080) QRect(1920,0 1920x1080)
Which is correct, as I'm running 2 1920x1080 monitors side to side.
Of course this is correct.
In your case the first virtual desktop spans over two physical monitors from (0,0) to (3840, 1080).
BUT!!!!!
As I told over and over again in my previous posts I can add p. e. a second virtual desktop which is positioned right to the first virtual desktop. In your case this second virtual desktop would span from (3840, 0) to (7680, 1080).
And as I tried to explain in the previous posts QDesktopWidget has no method to access the second virtual screen!!!! Which means a window's position on the second virtual screen (in your case p. e. (5000, 100) can not be validated with QDesktopWidget::screenGeometry.
So any other ideas how to accomplish this.
P.S. I am sorry it was not obvious in my first post that QDesktopWidget::screenGeometry was used. But if you read the manual carefully QDesktopWidget::availableGeometry does almost do the same like QDesktopWidget::screenGeometry.
PPS: I do not want to be mean kshegunov, but I will not reply to any non useful proposals anymore.
-
Of course this is correct.
In your case the first virtual desktop spans over two physical monitors from (0,0) to (3840, 1080).
BUT!!!!!
As I told over and over again in my previous posts I can add p. e. a second virtual desktop which is positioned right to the first virtual desktop. In your case this second virtual desktop would span from (3840, 0) to (7680, 1080).
And as I tried to explain in the previous posts QDesktopWidget has no method to access the second virtual screen!!!! Which means a window's position on the second virtual screen (in your case p. e. (5000, 100) can not be validated with QDesktopWidget::screenGeometry.
So any other ideas how to accomplish this.
P.S. I am sorry it was not obvious in my first post that QDesktopWidget::screenGeometry was used. But if you read the manual carefully QDesktopWidget::availableGeometry does almost do the same like QDesktopWidget::screenGeometry.
PPS: I do not want to be mean kshegunov, but I will not reply to any non useful proposals anymore.
@Hagen said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
As I told over and over again in my previous posts I can add p. e. a second virtual desktop which is positioned right to the first virtual desktop. In your case this second virtual desktop would span from (3840, 0) to (7680, 1080).
It would most certainly not! It will span from (0, 0) to (3840, 1080) just as the first virtual desktop. Moreover the "position" of one virtual desktop in regards to the other (as one sees it in the system menu/taskbar or w/e) has no bearing on the virtual desktop geometry.
Here's the test case for the doubtful:
#include <QApplication> #include <QMainWindow> #include <QTimer> #include <QDebug> int main(int argc, char ** argv) { QApplication app(argc, argv); QMainWindow window; window.show(); QTimer coordinatesTimer; coordinatesTimer.start(1000); QObject::connect(&coordinatesTimer, &QTimer::timeout, [&window] () -> void { qDebug() << window.geometry(); }); return QApplication::exec(); }
The code outputs the same geometry regardless on which virtual desktop I put the window, just as is expected.
And as I tried to explain in the previous posts QDesktopWidget has no method to access the second virtual screen!!!!
As I tried to explain, there's no practical difference between the first and second virtual desktop, thus
QDesktopWidget::desktop()
returns the same widget and the size of the virtual desktop (or any one of them) will be the same as the size of that widget (as per the Qt documentation).PS.
I suggest you drop the attitude if you hope to receive any other proposals, useful or otherwise. -
@Hagen said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
As I told over and over again in my previous posts I can add p. e. a second virtual desktop which is positioned right to the first virtual desktop. In your case this second virtual desktop would span from (3840, 0) to (7680, 1080).
It would most certainly not! It will span from (0, 0) to (3840, 1080) just as the first virtual desktop. Moreover the "position" of one virtual desktop in regards to the other (as one sees it in the system menu/taskbar or w/e) has no bearing on the virtual desktop geometry.
Here's the test case for the doubtful:
#include <QApplication> #include <QMainWindow> #include <QTimer> #include <QDebug> int main(int argc, char ** argv) { QApplication app(argc, argv); QMainWindow window; window.show(); QTimer coordinatesTimer; coordinatesTimer.start(1000); QObject::connect(&coordinatesTimer, &QTimer::timeout, [&window] () -> void { qDebug() << window.geometry(); }); return QApplication::exec(); }
The code outputs the same geometry regardless on which virtual desktop I put the window, just as is expected.
And as I tried to explain in the previous posts QDesktopWidget has no method to access the second virtual screen!!!!
As I tried to explain, there's no practical difference between the first and second virtual desktop, thus
QDesktopWidget::desktop()
returns the same widget and the size of the virtual desktop (or any one of them) will be the same as the size of that widget (as per the Qt documentation).PS.
I suggest you drop the attitude if you hope to receive any other proposals, useful or otherwise.Your test code executed:
Window on first virtual desktop:
QRect(844,222 200x100)Window moved to second virtual desktop
QRect(6284,222 200x100)In my previous posts I mentioned my three physical screens span only to (5720, 1200).
So again how can I check if geometry (QRect(6284,222 200x100)) is valid?
PS: I am sorry for my rude attitude. But I tried to explain the issue again and again. I hope you understand my problem with my machines' output of your test code.
-
Just out of curiosity I checked a Qt program I have that stores the position and size of the main window then returns the application to this position on next start. I have two virtual desktops minimum and regardless of which desktop I am on it always returned a coordinate relative to the top left corner. This is on OS X 10.10. I didn't check how GNU/Linux does this but I suspect it is comparable to what I saw on OS X. If Win10 handles virtual desktops by increasing the desktop size then that is pretty weird.
It is a good idea to verify that the program will restore it's position only if valid. I have seen some software not do this and usually windows get placed offscreen when something changes. The fix in this case would be to find the setting in the registry or INI file and manually adjust it - bleh!
Assuming Win10 does increase the desktop size then you have another problem when storing the position of windows. If you start up your program on virtual screen 1 but it was stored in coordinates relative to virtual screen 2 what happens then? Assuming you launch your program from a virtual window that is different then the one your program was saved in does Win10 automatically move to this virtual screen or does the user see nothing until they realize they need to move to this other virtual screen to see the program?
Maybe a Win32 direct call to get the number of virtual desktops and your own calculations based on the size of the desktop screen would work. Just wrap this section as something specific for Windows. It doesn't work this way on OS X and probably not on GNU/Linux.
-
Just out of curiosity I checked a Qt program I have that stores the position and size of the main window then returns the application to this position on next start. I have two virtual desktops minimum and regardless of which desktop I am on it always returned a coordinate relative to the top left corner. This is on OS X 10.10. I didn't check how GNU/Linux does this but I suspect it is comparable to what I saw on OS X. If Win10 handles virtual desktops by increasing the desktop size then that is pretty weird.
It is a good idea to verify that the program will restore it's position only if valid. I have seen some software not do this and usually windows get placed offscreen when something changes. The fix in this case would be to find the setting in the registry or INI file and manually adjust it - bleh!
Assuming Win10 does increase the desktop size then you have another problem when storing the position of windows. If you start up your program on virtual screen 1 but it was stored in coordinates relative to virtual screen 2 what happens then? Assuming you launch your program from a virtual window that is different then the one your program was saved in does Win10 automatically move to this virtual screen or does the user see nothing until they realize they need to move to this other virtual screen to see the program?
Maybe a Win32 direct call to get the number of virtual desktops and your own calculations based on the size of the desktop screen would work. Just wrap this section as something specific for Windows. It doesn't work this way on OS X and probably not on GNU/Linux.
@Rondog said in Check if a coordinate is a valid screen coordinate when using multiple desktops:
I didn't check how GNU/Linux does this but I suspect it is comparable to what I saw on OS X.
I have (I work on Linux, KDE 5) and it's as I've described - I always get the same geometry.
@Hagen
What you describe is really strange, @Rondog was faster than me, but my next question would've been: What OS are you using and which Qt version? This might be a bug, or some idiosyncrasy of the window manager.