4

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.

2
  • 2
    I do hope you have good reason for doing this as this could end up being very annoying if an application starts chasing me across my desktops. The main reason I use Virtual desktop's is to have "different" windows on each. Commented May 27, 2013 at 15:40
  • 1
    It's a small transparent widget to remember your actual task and need to be always visible for never forget the actual task (like a companion). Commented May 27, 2013 at 15:54

3 Answers 3

4

Under X11, you are supposed to set the _NET_WM_DESKTOP window property to 0xFFFFFFFF. I suspect there's no Qt API for that, so you'll have to litter the code with #ifdefs checking for X11 and call an appropriate X's function (nope, I don't know which one it is).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks you Jan for your help. I will try to use XChangeProperty ( X11/Xlib.h ) to setup the windows property and QX11Info present in Qt4.8 and QT5.1 to have access to X11 data from . I will post the solution when I have finished.
3

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 } 

2 Comments

Looks like data is a private member of QWidget and cannot be accessed by subclasses.
error: no matching function for call to 'objc_msgSend' […] note: candidate function not viable: requires 0 arguments, but 2 were provided Note arm64 Macbook Air.
2

Here is working example for MacOS 12 and M1 chip

WId windowObject = this->winId(); objc_object * nsviewObject = reinterpret_cast<objc_object *>(windowObject); objc_object * nsWindowObject = ((objc_object* (*)(id, SEL))objc_msgSend)(nsviewObject, sel_registerName("window")); int NSWindowCollectionBehaviorMoveToActiveSpace = 1 << 1; int NSWindowCollectionBehaviorTransient = 1 << 3; int NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8; int total = NSWindowCollectionBehaviorMoveToActiveSpace |NSWindowCollectionBehaviorTransient | NSWindowCollectionBehaviorFullScreenAuxiliary; ((objc_object* (*)(id, SEL, int))objc_msgSend)(nsWindowObject, sel_registerName("setCollectionBehavior:"), total); 

Found here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.