×
Namespaces

Variants
Actions

How to monitor application topmost status in Maemo 5

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata
Compatibility
Platform(s):
Symbian
Article
Created: divanov (21 Jan 2010)
Last edited: hamishwillee (11 Oct 2012)

This article shows how to monitor the topmost application from within a Qt application on Maemo (using GTK APIs)

Maemo provides an API for monitoring topmost status for Gtk applications using Hildon widgets: http://maemo.org/api_refs/5.0/5.0-final/hildon/HildonProgram.html You need to obtain instance of HildonProgram with hildon_program_get_instance() and then register your windows with hildon_program_add_window and then monitor status of is-topmost property.

Unfortunately there is no way to register Qt Window to HildonProgram. The only solution is to implement HildonProgram functionality in our Qt application. Note that this example should work on every platform with X11 support.

To accomplish this task we would need to subclass QApplication:

#ifndef APPLICATION_H
#define APPLICATION_H
 
#include <QApplication>
 
class Application : public QApplication
{
Q_OBJECT
public:
Application(int &argc, char **argv);
 
void registerWindow(WId wId);
void unregisterWindow(WId wId);
 
signals:
void topmostChanged(bool topmost);
 
private:
WId activeDesktopWindow(Display *display, WId rootWindow);
WId activeDesktopWindowGroup(Display *display, WId activeWindow);
bool x11EventFilter(XEvent *event);
QList<WId> windows;
bool topmost;
};
 
#endif // APPLICATION_H

We are going to reimplement X11 event hook: http://doc.trolltech.com/4.6/qapplication.html#x11ProcessEvent

#include <QX11Info>
#include <QDebug>
 
#include "application.h"
 
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
 
#ifdef Q_WS_HILDON
#define ACTIVE_APP_ATOM "_MB_CURRENT_APP_WINDOW"
#else
#define ACTIVE_APP_ATOM "_NET_ACTIVE_WINDOW"
#endif
 
Application::Application(int &argc, char **argv)
: QApplication(argc, argv), topmost(false)
{
}
 
void Application::registerWindow(WId window)
{
windows.append(window);
}
 
void Application::unregisterWindow(WId window)
{
windows.removeOne(window);
}
 
WId Application::activeDesktopWindowGroup(Display *display, WId activeWindow)
{
WId windowGroup;
XWMHints *wmHints = 0;
 
wmHints = XGetWMHints(display, activeWindow);
if (wmHints) {
windowGroup = wmHints->window_group;
XFree(wmHints);
} else
windowGroup = None;
 
return windowGroup;
}
 
WId Application::activeDesktopWindow(Display *display, WId rootWindow)
{
Atom realType;
int format, status;
unsigned long n, extra;
unsigned char *data = 0;
WId activeWindow;
Atom atom = XInternAtom(display, ACTIVE_APP_ATOM, false);
 
status = XGetWindowProperty(display, rootWindow, atom, 0L, 16L,
0, XA_WINDOW, &realType, &format,
&n, &extra, &data);
if (status == Success && realType == XA_WINDOW &&
format == 32 && n == 1 && data != NULL)
activeWindow = ((WId*)data)[0];
else
activeWindow = None;
 
if (data != 0)
XFree(data);
 
return activeWindow;
}
 
bool Application::x11EventFilter(XEvent *event)
{
static Qt::HANDLE rootWindow = QX11Info::appRootWindow();
static Atom activeAppAtom = XInternAtom(QX11Info::display(),
ACTIVE_APP_ATOM, false);
if (event->type == PropertyNotify) {
XPropertyEvent *pevent = (XPropertyEvent*)event;
if (pevent->window == rootWindow) {
if (pevent->atom == activeAppAtom) {
WId activeWindow = activeDesktopWindow(pevent->display,
rootWindow);
if(topmost != windows.contains(activeWindow)) {
topmost = !topmost;
emit topmostChanged(topmost);
qDebug() << "Application is topmost" << topmost;
}
}
}
}
 
return false;
}

The idea here is that root window has a property _MB_CURRENT_APP_WINDOW containing id of the currently topmost window. In order to know if our application is topmost we need to compare ids of our windows to the id of currently topmost window.

Them main.cpp would be something like this:

#include <QMainWindow>
 
#include "application.h"
 
int main(int argc, char *argv[])
{
Application a(argc, argv);
QMainWindow window;
 
a.registerWindow(window.winId());
window.show();
 
return a.exec();
}
This page was last modified on 11 October 2012, at 04:17.
51 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×