diff --git a/README.references.txt b/README.references.txt index 994058d..74cf38e 100644 --- a/README.references.txt +++ b/README.references.txt @@ -45,6 +45,10 @@ Intercept close event X11 https://stackoverflow.com/questions/1157364/intercept-wm-delete-window-on-x11 +Allowed actions + +https://stackoverflow.com/questions/28495586/x11-how-to-set-net-wm-allowed-actions + Qt X11 diff --git a/app/SysTray-X/windowctrl-unix.cpp b/app/SysTray-X/windowctrl-unix.cpp index 93324f7..5c2d156 100644 --- a/app/SysTray-X/windowctrl-unix.cpp +++ b/app/SysTray-X/windowctrl-unix.cpp @@ -207,6 +207,82 @@ void WindowCtrlUnix::minimizeWindow( Window window ) } +/* + * Remove window from taskbar + */ +void WindowCtrlUnix::skipTaskbarWindow( Window window, bool set ) +{ + char prop_name[] = "_NET_WM_STATE"; + Atom prop = XInternAtom( m_display, prop_name, True ); + Atom prop_skip_taskbar = XInternAtom( m_display, WindowStates[ STATE_SKIP_TASKBAR ].toUtf8(), True ); + + Atom type; + int format; + unsigned long remain; + unsigned long len; + unsigned char* list = nullptr; + + if( XGetWindowProperty( m_display, window, prop, 0, sizeof( Atom ), False, XA_ATOM, + &type, &format, &len, &remain, &list ) == Success ) + { + Atom* atom_list = reinterpret_cast( list ); + Atom* new_atom_list = nullptr; + bool present = false; + + if( len > 1 ) + { + /* + * Check and remove atom from list + */ + new_atom_list = new Atom[ len - 1 ]; + + for( unsigned long i = 0, o = 0; i < len; ++i ) + { + if( atom_list[ i ] == prop_skip_taskbar ) + { + present = true; + continue; + } + + new_atom_list[ o++ ] = atom_list[ i ]; + } + } + + if( set && !present ) + { + /* + * Set the atom + */ + XChangeProperty( m_display, window, prop, XA_ATOM, 32, PropModeAppend, reinterpret_cast( &prop_skip_taskbar ), 1 ); + } + else + if( !set && present ) + { + /* + * Remove the atom + */ + XChangeProperty( m_display, window, prop, XA_ATOM, format, PropModeReplace, reinterpret_cast( new_atom_list ), static_cast( len - 1 ) ); + } + + /* + * Cleanup + */ + if( new_atom_list ) + { + delete [] new_atom_list; + } + } + + /* + * Cleanup + */ + if( list ) + { + XFree( list ); + } +} + + /* * Normalize a window */ @@ -245,6 +321,8 @@ bool WindowCtrlUnix::generateEvent() #ifdef CHANGE_PROP +// XDeleteProperty( m_display, window, prop_skip_taskbar); + void WindowCtrlUnix::setAtomState() { char prop_name[] = "_NET_WM_STATE"; diff --git a/app/SysTray-X/windowctrl-unix.h b/app/SysTray-X/windowctrl-unix.h index 045e038..d7cbac8 100644 --- a/app/SysTray-X/windowctrl-unix.h +++ b/app/SysTray-X/windowctrl-unix.h @@ -151,6 +151,8 @@ class WindowCtrlUnix : public QObject */ void normalizeWindow( Window window ); + void skipTaskbarWindow( Window window, bool set ); + private: /** diff --git a/app/SysTray-X/windowctrl.cpp b/app/SysTray-X/windowctrl.cpp index d0b9c73..674bbdf 100644 --- a/app/SysTray-X/windowctrl.cpp +++ b/app/SysTray-X/windowctrl.cpp @@ -54,7 +54,9 @@ void WindowCtrl::slotWindowTest2() // Do something. unsigned long win_id = getWId(); + skipTaskbarWindow( win_id, true ); minimizeWindow( win_id ); + // normalizeWindow( win_id ); /* @@ -77,6 +79,7 @@ void WindowCtrl::slotWindowTest3() // Do something. unsigned long win_id = getWId(); + skipTaskbarWindow( win_id, false ); normalizeWindow( win_id ); emit signalConsole("Test 3 done");