PDA

View Full Version : Can't seem to get global screen position



huilui
22nd August 2012, 22:48
Hi guys,

I've got a little problem: A little app of mine has a screenshot of the current desktop set as background. The application always runs in fullscreen. It all works just perfectly on a single monitor. However, on a dual-head system I run into some problems getting the right part of the screenshot to be set as background.

More details: I've got my primary monitor on the right and a secondary monitor on the left. I simply cannot detect reliably what screen I'm running the app on or what global position the app has. Some code:



// Getting the screenshot
QPixmap screen = QPixmap::grabWindow(QApplication::desktop()->winId());

// Here's one problem: Getting the current screen size (see note after code snippet).
globScreenRect = QApplication::desktop()->screenGeometry();

// The QPixmap bg is the new background pixmap, containing screen and an overlay
QPainter painter(&bg);
painter.setCompositionMode(QPainter::CompositionMo de_SourceOver);
int x = 0;
int y = 0;
int w = screen.width();
int h = screen.height();
if(QApplication::desktop()->numScreens() == 2) {
// Detecting if app is run on primary or secondary screen and adjust screenshot accordingly
if(globScreenRect.x() != 0) {
x = w-globScreenRect.width();
w = globScreenRect.width();
} else {
w = globScreenRect.width();
}

}
painter.drawPixmap(0, 0, overlay.width(), overlay.height(), screen,x,y,w,h);
painter.drawPixmap(overlay.rect(), overlay);
painter.end();


The problem seems to be detecting the current active screen size. "screenGeometry()" always returns the geometry of the primary screen (i.e. QRect(1024,0 1366x768) ). I could get the geometry of the secondary screen simply by using "screenGeometry(1)", but how do I know if the app is running on the primary or secondary screen?

If I try to find out the current global position of the app by "this->pos().x()" or even "mapToGlobal(this->pos()).x()", it always gives me "0", i.e. the absolute top left position... According to the Qt Doc: "mapToGlobal - Translates the widget coordinate pos to global screen coordinates.", but it somehow doesn't do that...?

Am thankful for any help :)

huilui

Coises
23rd August 2012, 01:19
More details: I've got my primary monitor on the right and a secondary monitor on the left. I simply cannot detect reliably what screen I'm running the app on or what global position the app has.

Is QDesktopWidget::primaryScreen() (http://doc.qt.nokia.com/latest/qdesktopwidget.html#primaryScreen-prop) any use? The documentation is inconsistent: it says that property “holds the index of the screen that is configured to be the primary screen on the system”; but in the general description for QDesktopWidget it says, “For an application, the screen where the main widget resides is the primary screen. This is stored in the primaryScreen property. (http://doc.qt.nokia.com/latest/qdesktopwidget.html#use-of-the-primary-screen)”

(Lord knows what the main widget is supposed to mean.)

ChrisW67
23rd August 2012, 01:40
QDesktopWidget::screenNumber() with your main window should tell you which screen the majority of your main window is on. Compare that return to the QDesktopWidget::primaryScreen() and you know whether you are on the primary screen or not.

huilui
23rd August 2012, 13:39
Thanks guys for the ideas. I added this line to the code:


qDebug() << QApplication::desktop()->primaryScreen() << "-" << QApplication::desktop()->screenNumber() << "-" << QApplication::desktop()->screenCount();


However, no matter what screen I run the app on, I always get the following output:
0 - 0 - 2

It just doesn't make sense...

amleto
23rd August 2012, 15:01
well, it kinda makes sense when you read:

“For an application, the screen where the main widget resides is the primary screen. This is stored in the primaryScreen property.”
- Coises.

now you have to check that the sizes of the different screens always correspond correctly?

Coises
23rd August 2012, 17:29
Thanks guys for the ideas. I added this line to the code:


qDebug() << QApplication::desktop()->primaryScreen() << "-" << QApplication::desktop()->screenNumber() << "-" << QApplication::desktop()->screenCount();


However, no matter what screen I run the app on, I always get the following output:
0 - 0 - 2

It just doesn't make sense...

Per ChrisW67’s suggestion, what happens if you replace QApplication::desktop()->screenNumber() with QApplication::desktop()->screenNumber(widget), where widget is a pointer to your window widget? (See: QDesktopWidget::screenNumber)

Similarly, note that QDesktopWidget::availableGeometry can take a QWidget* argument.

huilui
24th August 2012, 15:47
well, it kinda makes sense when you read:

“For an application, the screen where the main widget resides is the primary screen. This is stored in the primaryScreen property.”
- Coises.

now you have to check that the sizes of the different screens always correspond correctly?

But then I should get different screen resolutions for the primary screen each time. But the following always returns "QRect(1024,0 1366x768)"...
QApplication::desktop()->screenGeometry(QApplication::desktop()->primaryScreen())



Per ChrisW67’s suggestion, what happens if you replace QApplication::desktop()->screenNumber() with QApplication::desktop()->screenNumber(widget), where widget is a pointer to your window widget? (See: QDesktopWidget::screenNumber)

Similarly, note that QDesktopWidget::availableGeometry can take a QWidget* argument.

Hm, when I try
QApplication::desktop()->screenNumber(this) I get a slightly different output to the qDebug() statement: "0 - 1 - 2". But again, it's the exact same no matter what screen I start the app on...
I'll have a look at QDesktopWidget::availableGeometry() later-on when I'm back home... hopefully that'll work!!

Coises
24th August 2012, 19:08
But again, it's the exact same no matter what screen I start the app on...

For me, that would be where I give up, conclude that Qt has missed (again), and just work out how to do it with the native API for whatever operating system(s) this will run on.

Based only on my quite limited personal experience, I’d put the odds at 50-50 that you’ll never find a pure Qt solution, so this where it become more time/cost-effective to forget Qt and use the native API while you still have a few shreds of sanity left.

huilui
26th August 2012, 23:48
For me, that would be where I give up, conclude that Qt has missed (again), and just work out how to do it with the native API for whatever operating system(s) this will run on.

Based only on my quite limited personal experience, I’d put the odds at 50-50 that you’ll never find a pure Qt solution, so this where it become more time/cost-effective to forget Qt and use the native API while you still have a few shreds of sanity left.

Hm, I think you're right. It might be better to stop messing around with Qt trying to get that to work and just do it without Qt... It'l probably take a good while, but then it will (hopefully) work at least.

Thanks to all of you guys for your help :)

Coises
27th August 2012, 00:20
It'l probably take a good while, but then it will (hopefully) work at least.

If it’s Windows, see the topics under:

Multiple Display Monitors (http://msdn.microsoft.com/en-us/library/windows/desktop/dd145071(v=vs.85).aspx)

especially the example here:

Positioning Objects on a Multiple Display Setup (http://msdn.microsoft.com/en-us/library/windows/desktop/dd162826(v=vs.85).aspx)

and the references here:

Multiple Display Monitors Functions (http://msdn.microsoft.com/en-us/library/windows/desktop/dd145072(v=vs.85).aspx)

I only have one monitor here, so I can’t tell you if all that works as advertised. I imagine Qt is attempting to use those same functions. (To get an HWND from a Qt window, use QWidget::winId.)

huilui
27th August 2012, 09:13
Thanks for the links coises!! However, my app is used mostly in Linux (don't know of anybody who tried to run it in Windows yet)...