diff options
Diffstat (limited to 'kwin/clients/PORTING')
-rw-r--r-- | kwin/clients/PORTING | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/kwin/clients/PORTING b/kwin/clients/PORTING new file mode 100644 index 000000000..9a5fb9f6b --- /dev/null +++ b/kwin/clients/PORTING @@ -0,0 +1,159 @@ +It's suggested you check sources of some KDE CVS decoration if in doubts or in need of an example. +Also, the API is documented in the .h header files. + +Makefile.am: +- Change kwin_ to kwin3_ (in LDFLAGS, LIBADD, kde_module_LTLIBRARIES, SOURCES). +- Make sure LDFLAGS contains $(KDE_PLUGIN) and -module . +- Add -lkdecorations to LIBADD. +- Do NOT rename the directory where the .desktop file is installed ( $(kde_datadir)/kwin/ ). + +.desktop file: +- Change kwin_ to kwin3_ in X-KDE-Library. + +Sources: +- There are no kwin/something.h includes, and don't use the KWinInternal namespace. +- Use QToolTip instead of KWinToolTip. +- Use QButton instead of KWinButton, QToolButton instead of KWinToolButton and QWidget + instead of KWinWidgetButton. +- For tooltips, use simply QToolTip::add(). +- Change Client* to MyClient* (or whatever is your main client class) in your MyButton. +- Pass parent->widget() to QButton constructor in your MyButton constructor. +- Make your MyClient class inherit from KDecoration instead of Client. +- Make MyClient constructor take KDecorationBridge* and KDecorationFactory* as arguments, + and pass these arguments to KDecoration constructor. +- Except for data members initialization, make the constructor empty, move everything + to void MyClient::init(). +- As the first thing in init(), call createMainWidget(); if your client class took some + flags such as WResizeNoErase, pass them to this function. +- Then, do 'widget()->installEventFilter( this );'. +- Implement MyClient::eventFilter() - as MyClient is now no longer QWidget, you need the event + filter to call all the functions that used to be called directly. Usually, it's something + like: +===== +bool MyClient::eventFilter( QObject* o, QEvent* e ) +{ + if ( o != widget() ) + return false; + + switch ( e->type() ) + { + case QEvent::Resize: + resizeEvent( static_cast< QResizeEvent* >( e ) ); + return true; + + case QEvent::Paint: + paintEvent( static_cast< QPaintEvent* >( e ) ); + return true; + + case QEvent::MouseButtonDblClick: + mouseDoubleClickEvent( static_cast< QMouseEvent* >( e ) ); + return true; + + case QEvent::Wheel: + wheelEvent( static_cast< QWheelEvent* >( e )); + return true; + + case QEvent::MouseButtonPress: + processMousePressEvent( static_cast< QMouseEvent* >( e ) ); + return true; + + case QEvent::Show: + showEvent( static_cast< QShowEvent* >( e ) ); + return true; + + default: + return false; + } +} +===== +- In MyClient, 'this' will have to be often replaced with 'widget()', pay special attention + to cases where this won't cause compile error (e.g. in connect() calls, which take QObject* ). +- Also, many calls may need 'widget()->' prepended. +- Layout is created in init(), so call createLayout() directly there (if it's implemented). +- Remove calls to Client methods (Client::resizeEvent() and so on). +- Replace Options:: with KDecorationOptions:: . +- Replace 'options' with 'options()' in MyClient (which is KDecoration::options()), if often used + outside of MyClient, you may want to create (this assumes your code is in its namespace): +===== +inline const KDecorationOptions* options() { return KDecoration::options(); } +===== +- Options for colors need 'Color' prepended (e.g. 'ColorButtonBg'). +- Replace miniIcon() with getting the right pixmap from icon() (usually + 'icon().pixmap( QIconSet::Small, QIconSet::Normal )' ). +- Replace stickyChange() with desktopChange(), and test isOnAllDesktops(). +- Replace Sticky with OnAllDestops. +- Replace iconify with minimize. +- Change activeChange(bool) to activeChange(), and use isActive() to check the state. + Similar for desktopChange, captionChange(), iconChange(), maximizeChange(). +- Replace 'contextHelp()' with 'showContextHelp()'. +- WindowWrapperShowEvent() is gone, simply use showEvent() filtered by the event filter if needed. +- Change 'animateIconifyOrDeiconify()' to 'animateMinize()', if it's empty, simply remove it. + Make sure it doesn't reenter the event loop (no kapp->processEvents()). +- Buttons should use explicit setCursor() if they don't want cursor set by mousePosition(). + I.e. usually call setCursor( ArrowCursor ) in your MyButton. +- In the part where you insert windowWrapper() into the layout, i.e. something like +===== + layout->addWidget( windowWrapper()); +===== + replace it with something like +===== + if( isPreview()) + layout->addWidget( new QLabel( i18n( "<center><b>MyDecoration</b></center>" ), widget())); + else + layout->addItem( new QSpacerItem( 0, 0 )); +===== +- Implement MyClient::minimumSize(). +- Handling maximization - to change vertical or horizontal maximalization, use e.g. + 'maximize( maximizeMode() ^ MaximizeVertical', to change normal maximalization, i.e. after + left-clicking on the button, use + 'maximize( maximizeMode() == MaximizeFull ? MaximizeRestore : MaximizeFull );' (which also + means that there's also no maximize() slot). + Also, if your decoration button has only two visual states representing the maximalization state, + it's recommended that it shows the maximized state only for MaximizeFull state. +- Make sure the decoration matches the window state after init() is finished, that is, that + the buttons represent correctly the maximalization, on-all-desktops etc. states. As the + simplest solution, you can call maximizeChange(), desktopChange(), etc. at the end + of init(). +- Use 'titlebarDblClickOperation()' for performing the application after doubleclicking + the titlebar. +- Implement borders() returning the width of the top,left,right and bottom border. You may + check values like 'maximizeMode() == MaximizeFull && !options()->moveResizeMaximizedWindows()' + to check whether you can disable some borders completely. + Note that your painting code must of course match these sizes. +- If your code uses XGrabServer() or XUnGrabServer(), replace them with (un)grabXServer(). +- In cases where you call some function from the KDecoration API that can possibly destroy + the decoration (e.g. showWindowMenu() or closeWindow()), make sure to use exists() if some more + code will follow this call. Refer to showWindowMenu() documentation for an example. +- Create class MyFactory inheriting from KDecorationFactory, and move the code that was + in 'extern "C"' to it: From init() to constructor, from deinit() to destructor, from allocate() + or create() to createDecoration(). Pass the KDecorationBridge* argument and 'this' to created + MyClient objects. If createDecoration() needs to know the window type (e.g. it used the tool + argument), use windowType() similarly like in KDecoration, and pass it the KDecorationBridge* + argument. +- Add something like this: +===== +extern "C" +{ + KDecorationFactory *create_factory() + { + return new MyNamespace::MyFactory(); + } +} +===== +- The reset handling has changed: There's no signal resetClients(), and no + slotResetAllClientsDelayed(). If your MyClient has some slotReset(), make it + reset( unsigned long ), where the argument is mask of things that have changed ( SettingXYZ ). + If you have some global function that handles resetting, make it + MyFactory::reset( unsigned long ). Try to minimize the effects of the changed things, + e.g. if only the color setting has changed, doing a repaint is often enough, and there's no need + to recreate the decorations. If you need to recreate the decorations, return true + from MyFactory::reset(), otherwise, you may call resetDecorations() to call reset() in all + MyClient instances. +- Implement resize() to resize the decoration to the given size + (usually 'widget()->resize( s );' is enough). +- Review mousePosition() if it's implemented. Position constants need 'Position' prepended, + e.g. Top -> PositionTop. +- Note that you cannot use "appdata" with KStandardDirs, as the decoration will be used + also in other applications than kwin. +- Implement all missing pure virtual functions. For mousePosition(), you may call + KDecoration::mousePosition() if it's sufficient. |