There are situations where you don’t want text to be selected and images to be dragged in your QWebView (See my previous post). Qt does not provide support out of the box, but this is fairly straightforward to do. I wrote a quick hack to demonstrate, get it here.
Almost a year back, I was looking for a maintainer for kdocker. I had practically given up, when out of the blue John contacted me to be the new maintainer. What more, he had already ported it Qt4! That made handing over maintainership to him a no-brainer
Integrating the web into desktop apps is now incredibly easy thanks to Qt WebKit. Qt WebKit also allows us to embed any Qt widget inside the html. This feature makes it extremely tempting to develop full blown desktop applications using Qt WebKit – your interface is entirely designed using html/css (instead of .ui) and you as a C++ developer decide what parts are best done in Qt/C++ and embed them into the html page.
The above scheme works very well (for the most part). However, there are a lot of features that make our applications feel native, that we take for granted in desktop apps when using Qt/C++ but not so when using Qt WebKit. So here is a list of short comings that you should know about.
1. Focus handling – Tab focus doesn’t work at all when navigating from html into a c++ plugin and vice versa.
2. Keyboard accelerators – In html, you can specify accelerator using ‘accesskey’. They don’t seem to work in QtWebKit. They do work in google chrome, so must be something to do with the Qt port.
3. Text can be selected and images can be dragged – Your main ui is html, what did you expect ?
4. Plugins will get deleted if you hide them – If you hide your C++ plugin/widget using ‘display: none’, Qt/WebKit will delete it. In your traditional Qt program, all your data is part of the widget – now it’s all gone. To prevent this, you have to write all your widgets to use the model-view paradigm. An alternative is to use ‘visibility: hidden’ which won’t delete the plugin but the plugin will continue to hog space in the layout. Side note: In Qt 4.4.x, plugins weren’t deleted (aka leak). Starting Qt 4.5.x, they were deleted – we found this problem when our app starting crashing gloriously when we moved to Qt 4.5.x.
5. Fluid layouts – When the windows resizes, UI elements inside are expected to reposition and resize nicely; the window must have a nice minimum size – that is all done by QLayout does. This is really hard to get right when using html. You will most likely end up writing js layouting code.
6. Moving data back and forth is slow – Passing Qt types from C++ to JS works very well using QJson. Converting complex types like a QPixmap to html img is really really slow, since you have to convert in into png first. Also, using this method crashes Asus laptops/Windows, probably some graphics card issue, nevertheless your app has to deal with it.
8. RTL – Qt will layout your widgets automatically when your app is run in a RTL environment. With HTML, you will have to provide an alternate html file, do your own RTL detection, implement sizing fixes to elements for different languages and so on.
9. Translations – Qt provides you linguist, lrelease, lupdate. When using HTML, you will have to roll out your own translation framework (this is an awful lot of work).
10. Misc – There are other minor problems depending on your Qt version – the default fonts of html and qt didn’t match. There was a time when a 12pt font of Qt and 12 pt font of webkit don’t match (this seems to be fixed now). Displaying plugins inside divs had some artifacts.
Note that the above is not a case against using Qt/WebKit for developing desktop apps since they can all be worked around. It’s more for you to know what you will be up against if you decide to go down this road.
Update 1: Added note on rtl and translations
It’s been a year and a half since my good friend Roopesh and I started this company, ForwardBias Technologies. Starting our own business has been nothing short of exhilarating and fabulous. Estimating turnover, pricing, talking to customers, deciding company vision/direction is all very very thrilling!
Since inception, we have been focusing our energies on Qt consulting. We have managed to carve a nice niche for ourselves in “high end” Qt consulting market – we have developed paint engines (yes, plural!), custom styles, a really cool full blown webkit application (which we will blog about shortly), hacked on koffice (for only a short while, unfortunately) and a lot more. I think I can safely say that our customers are enthralled with our work – every one of them has offered us more work.
And, we are also working on our hush-hush product in parallel. And despite me saying it’s all very exciting and fun, we are also getting a wee bit exhausted with all the action. It’s just two of us and we need more people!
So, am very happy to say, we are hiring! We have spoken our hearts out in that page and what we would like to repeat is that this is a company made for developers by developers and we are looking for fearless programmers – our customers and product requires one to constantly learn new things on the job and become good at it very fast.
And of course, some bonus points if you are already know KDE/Qt development.
My tata wimax connection works well most of the time but it has a supremely annoying feature that to get connected, one is redirected to login in their login site (pretty much how the internet connection works in many hotels). If you are idle for sometime, it will auto logoff. Since my internet connection is not so fast, I usually download over the night and open a keepalive window.
This worked well up until a couple of months back. Now they seem to have decided to disconnect users at random times regardless of internet activity. Not to be deterred by the challenge, I started thinking of how to work around this. The login screen looks like this:
I needed something that keeps logging me in automatically. Qt/WebKit was the obvious choice. It would have been trivial had the post URL of the above form not been dynamic (i.e it has a magic session number in the POST url).
So, here’s what I had to do:
1. Keep loading some website at periodic intervals. Check if I get redirected to their login page. It was a bit tricky to use Qt/WebKit to detect a redirect (in fact, there are two redirects); one has to resort to using timers and check if all the redirection has been done and the pages have been completely loaded.
You can find the git repo here (btw, Assembla rocks!).
It struck me later that I probably didn’t need Qt WebKit at all. I think a html/js loading a website periodically in a separate frame and trying to logon if necessary could have worked as well.
It’s been a long busy month. With the impending 2.0 release, I have been hacking away polishing up ODF list support for KWord.
Here’s a list of improvements coming up
- Support for saving and loading ODF text:list. This was a lot of work. ODF lists are complex beasts. It was major help that Thomas Zander had done a lot of work in supporting lists and numbering of lists in the layout. We now support the important ODF 1.1 list attributes like space-after, min-label-distance, text-align, min-label-width
- Support for editing lists and sublists, similar to OOo and MS Word. Press tab to increase the indentation level. Press Backtab to decrease the level
- Support for loading and saving lists as numbered-paragarph. This means that documents written with KWord 1.x can be loaded up with 2.0. However, KWord does not save as numbered-paragraph because neither OOo nor KWord 1.x can load it correctly (KWord 1.x seems to use the optional text:number tag to determine numbering).
- Support for list headers
- Support for unnumbered paragraphs. In ODF, a list-item can contain multiple paragraphs. As a result, the first backspace that you press at the beginning of a list-item makes the paragraph an “unnumbered paragraph”. The second backspace ends the list.
- Quirks to make lists behave the save just like OOo. OOo seems to make a few assumptions that are not stated in the spec – Two disjoint text:lists that follow the same list style are considered to be one list (this affects numbering and that changing the style of one list changes the other). For better or worse, we go out of the way to mimic OOo here.
Here’s a screenshot:
- Fixed whitespace normalization. See 853298 for details.
- Switched the default template to odt!
- Lots of refactoring, cleanup and redesign.
I have been using the N810 for a week now. It’s plain awesome – its decently fast and most importantly things just work. The feel of the device is so good compared to my pricy 6110 S60 crap. I am really hoping Nokia will release a maemo based image for 6110 someday.
My previous experience with Nokia (device) development was with S60/Symbian which was just plain depressing. The Carbide would keep crapping out at the most inappropriate moments, the final product behaves differently than the simulator, the… Ah, I should stop here, I love bitching about S60 and Symbian. And I can do it forever
So with some trepidation, yesterday I decided to get my N810 setup for development. It was so simple that I was sure I was missing something. Qt Hello World was up and running in short time. I wrote a small tutorial on how to get Qt installed on maemo.
Immediate thoughts: Maemo looks like a very hacker friendly platform. A big thing for me is that compared to the S60, I actually want to write apps for the N810.
Next Stop – Getting KOffice running.
Standard excuse – I have no time. I am looking for maintainer(s) for KDocker. Unlike it’s name suggests, it’s not a KDE application, it’s plain Qt 3.
Over the years (literally), I have just ignored bugs, feature requests, patches from many (~100) people. Today, I got a mail from Peter Toushkov with updated bulgarian translations. IIRC, there are two new language translations archived somewhere in my gmail account. I feel very bad about all the effort put in by these people go waste. I should have written this maybe a year back, but better late than never.
Why would you want to work on it?
– You get to learn a lot of Qt and X11 . In fact, this knowledge is what helped me write QSystemTrayIcon at TT . Some of the code in there is quite hard to get right on all WM.
– Actually, there is no maintanence work. The first task would probably be to rewrite everything in Qt4 using QSystemTrayIcon and still call the new code kdocker.
– Many people have mailed me with lots of innovative ideas which would be nice to implement.
Contact me, if you are interested.
As promised in my previous blog post, I have written a couple of tutorials explaining how ODF document editing/saving works in KWord.
As before, please feel free to fix it, if you find something obviously wrong. I have to also point out that I wrote the articles primarily so I can help understand the code; I haven’t put in a lot of effort into spell checking, grammar, structure. Feel free to fix the style/language too.
Exercise: Spot the bug in KoTextShapeData::saveOdf() . It is the reason why styles aren’t saved when a ODF document is saved in KWord. I am fixing just that, btw