Few days ago I had a chance to play for a wile with my Nokia N950. I’ve tried to port some Qt application from Symbian to Harmattan and unfortunately faced with lack of support of QWidget and QGraphicsView based applications in that platform. Some of my findings are below:
- QWidget-based objects don’t have any native style support and looks exactly as in Windows. Which is obviously awful
- There is no working API to set application window orientation. Moreover, the default orientation is landscape! Some interesting details are here.
- In case you are using QML-based UI you should rewrite it and use Window\PageStack\Page classes to be able to change your app orientation. Or probably rotation trick will work for it, but i didn’t check.
That seems a bit unfair for me as there are Qt 4.7.x libs preinstalled and QWidgets\QGraphicsView are still mainstream ways to develop UI for it. That might cause a lot of problems during the porting of Symbian\Maemo5 applications to Harmattan.
In my case the app i tried to port contains QGraphicsView with some pixmap elements in it and some QPushButtons with images over them (without text). So i’m luckely avoid QWidget-style problem.
Its launched on N950 without any changes in sources and looks great (of course due to devices screensize the images were smaller). But it had landscape orientation. And i spent a lot of time on fixing such a simple thing. Finally, i have managed to rotate UI using the following:
- Call of QGraphicsView::rotate(270) to automatically rotate all items in it.
- Change x and y in event handlers code to fix some animation framework staff.
- Just move QWidget-based buttons position and rotate all images in it.
And one more step (that’s actually the real reason of that post and the only thing I have to share). The system itself still treats your application window as landscape oriented. That mean, for example, that if the "Top slide closes the application" setting is switched on in your device it will not work correctly for your app window. Actually, it will but with wrong sliding direction (right side is top for landscape oriented windows). To fix this behavior and let system know that your window is portrait oriented you should call following function for your top-level widget:
Normal
0
false
false
false
RU
X-NONE
X-NONE
Normal
0
false
false
false
RU
X-NONE
X-NONE
#ifdef Q_OS_UNIX
#include <QX11Info>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#endif
enum MyOrientation
{
Landscape = 0,
Portrait = 270,
LandscapeInverted = 180,
PortraitInverted = 90
};
static void writeX11OrientationAngleProperty(QWidget* widget, MyOrientation orientation= Portrait)
{
#ifdef Q_WS_X11
if (widget)
{
WId
id = widget->winId();
Display *display = QX11Info::display();
if (!display) return;
Atom
orientationAngleAtom = XInternAtom(display, "_MEEGOTOUCH_ORIENTATION_ANGLE", False);
XChangeProperty(display, id, orientationAngleAtom, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&orientation, 1);
}
#endif
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
Form f;
writeX11OrientationAngleProperty(&f);
f.showFullScreen();
return a.exec();
}
The code was copy-pasted and adopted from some MeeGo sources.
Unfortunately it just tells the system that your window orientation is changed, so OS can manage it accordingly. But it doesn’t change orientation of content inside window so it doesn’t affect window rendering.
