Search code examples
c++qtgnomekde-plasma

Keep a application window always on current desktop on linux and mac


I search a way to put a QWidget window of a Qt application always on the current desktop/workspace. When I change the virtual desktop, I need my window to be automatically visible on the new current virtual desktop.

I search a solution that works at minimum on gnome, kde on linux and mac os.

I think the first step is to detect when virtual desktop is change, I don't know if Qt have a API for that or if I need to implement it for each desktop solution.


Solution

  • Thanks to Jan Kundrát for his help (Previous comment https://stackoverflow.com/a/16777496/1045832 ).

    Solution for linux X11 :

    #ifdef Q_WS_X11 //only define on Qt 4.X 
    #include <QX11Info> //Only on Qt 4.X , return expected in Qt 5.1
    #include <X11/Xlib.h>
    #include <X11/Xatom.h>
    #endif
    
    YourWidget::YourWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::YourWidget)
    {
    
    #ifdef Q_WS_X11 //only define on Qt 4.X 
        unsigned long data = 0xFFFFFFFF;
        XChangeProperty (QX11Info::display(),
                         winId(),
                         XInternAtom(QX11Info::display(), "_NET_WM_DESKTOP", False),
                         XA_CARDINAL,
                         32,
                         PropModeReplace,
                         reinterpret_cast<unsigned char *>(&data), // all desktop
                         1);
    #endif
    }
    

    Put this on your .pro

    unix:!macx {
        LIBS += -lX11
    }
    

    Solution for macos X :

    #include <objc/objc-runtime.h>
    
    WId windowObject = this->winId();
    objc_object * nsviewObject = reinterpret_cast<objc_object *>(windowObject);
    objc_object * nsWindowObject = objc_msgSend(nsviewObject, sel_registerName("window"));
    int NSWindowCollectionBehaviorCanJoinAllSpaces = 1 << 0;
    objc_msgSend(nsWindowObject, sel_registerName("setCollectionBehavior:"), NSWindowCollectionBehaviorCanJoinAllSpaces);
    

    Put this on your .pro

    macx {
        LIBS += -lobjc
    }