diff --git a/app/SysTray-X/windowctrl-unix.cpp b/app/SysTray-X/windowctrl-unix.cpp index a4ea348..a24ff30 100644 --- a/app/SysTray-X/windowctrl-unix.cpp +++ b/app/SysTray-X/windowctrl-unix.cpp @@ -268,14 +268,12 @@ void WindowCtrlUnix::minimizeWindow( quint64 window, bool hide ) return; } - Window win = static_cast( window ); - if( hide ) { - hideWindow( win, hide ); + hideWindow( window, hide ); } - XIconifyWindow( m_display, win, m_screen ); + XIconifyWindow( m_display, static_cast( window ), m_screen ); XFlush( m_display ); } @@ -290,16 +288,22 @@ void WindowCtrlUnix::normalizeWindow( quint64 window ) return; } + hideWindow( window, false ); + Window win = static_cast( window ); - hideWindow( win, false ); + Atom msg_atom = XInternAtom( m_display, "_NET_ACTIVE_WINDOW", False ); + if( msg_atom == None ) + { + return; + } XEvent event = { 0 }; event.xclient.type = ClientMessage; event.xclient.serial = 0; event.xclient.send_event = True; - event.xclient.message_type = XInternAtom( m_display, "_NET_ACTIVE_WINDOW", False ); - event.xclient.window = static_cast( window ); + event.xclient.message_type = msg_atom; + event.xclient.window = win; event.xclient.format = 32; XSendEvent( m_display, m_root_window, False, SubstructureRedirectMask | SubstructureNotifyMask, &event ); @@ -310,7 +314,7 @@ void WindowCtrlUnix::normalizeWindow( quint64 window ) /* - * Remove window from taskbar + * Hide window to system tray */ void WindowCtrlUnix::hideWindow( quint64 window, bool set ) { @@ -319,80 +323,20 @@ void WindowCtrlUnix::hideWindow( quint64 window, bool set ) return; } - Window win = static_cast( window ); - - 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, win, prop, 0, sizeof( Atom ), False, XA_ATOM, - &type, &format, &len, &remain, &list ) == Success ) + if( set ) { - 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, win, prop, XA_ATOM, 32, PropModeAppend, - reinterpret_cast( &prop_skip_taskbar ), 1 ); - } - else - if( !set && present ) - { - /* - * Remove the atom - */ - XChangeProperty( m_display, win, prop, XA_ATOM, format, PropModeReplace, - reinterpret_cast( new_atom_list ), static_cast( len - 1 ) ); - } - - /* - * Cleanup - */ - if( new_atom_list ) - { - delete [] new_atom_list; - } + sendEvent( window, + "_NET_WM_STATE", + _NET_WM_STATE_ADD, + static_cast( XInternAtom( m_display, "_NET_WM_STATE_SKIP_TASKBAR", False ) ) ); } - - /* - * Cleanup - */ - if( list ) + else { - XFree( list ); + sendEvent( window, + "_NET_WM_STATE", + _NET_WM_STATE_REMOVE, + static_cast( XInternAtom( m_display, "_NET_WM_STATE_SKIP_TASKBAR", False ) ) ); } - - XFlush( m_display ); } @@ -408,14 +352,14 @@ void WindowCtrlUnix::deleteWindow( quint64 window ) Window win = static_cast( window ); - Atom prop = XInternAtom( m_display, "WM_PROTOCOLS", True ); - if( prop == None ) + Atom msg_atom = XInternAtom( m_display, "WM_PROTOCOLS", True ); + if( msg_atom == None ) { return; } Atom delete_prop = XInternAtom( m_display, "WM_DELETE_WINDOW", False ); - if( prop == None ) + if( delete_prop == None ) { return; } @@ -423,7 +367,7 @@ void WindowCtrlUnix::deleteWindow( quint64 window ) XEvent event; event.xclient.type = ClientMessage; event.xclient.window = win; - event.xclient.message_type = prop; + event.xclient.message_type = msg_atom; event.xclient.format = 32; event.xclient.data.l[0] = static_cast( delete_prop ); event.xclient.data.l[1] = CurrentTime; @@ -458,6 +402,37 @@ QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( Display *dis } +/* + * Send a X event + */ +void WindowCtrlUnix::sendEvent( quint64 window, const char* msg, long action, + long prop1, long prop2, long prop3, long prop4 ) +{ + Window win = static_cast( window ); + + Atom msg_atom = XInternAtom( m_display, msg, False ); + if( msg_atom == None ) + { + return; + } + + XEvent event; + event.xclient.type = ClientMessage; + event.xclient.serial = 0; + event.xclient.send_event = True; + event.xclient.message_type = msg_atom; + event.xclient.window = win; + event.xclient.format = 32; + event.xclient.data.l[0] = action; + event.xclient.data.l[1] = prop1; + event.xclient.data.l[2] = prop2; + event.xclient.data.l[3] = prop3; + event.xclient.data.l[4] = prop4; + + XSendEvent( m_display, DefaultRootWindow( m_display ), False, SubstructureRedirectMask | SubstructureNotifyMask, &event ); +} + + /* * Get the title of the window */ diff --git a/app/SysTray-X/windowctrl-unix.h b/app/SysTray-X/windowctrl-unix.h index 938be1c..7ad40e7 100644 --- a/app/SysTray-X/windowctrl-unix.h +++ b/app/SysTray-X/windowctrl-unix.h @@ -55,6 +55,16 @@ class WindowCtrlUnix : public QObject TYPE_NORMAL }; + /* + * State actions + */ + enum StateActions + { + _NET_WM_STATE_REMOVE = 0, + _NET_WM_STATE_ADD, + _NET_WM_STATE_TOGGLE + }; + /* * Window states */ @@ -227,6 +237,20 @@ class WindowCtrlUnix : public QObject */ QList< WindowItem > listXWindows( Display* display, quint64 window, int level = 0 ); + /** + * @brief sendEvent. Send an event. + * + * @param window Event target. + * @param msg The message + * @param action The action for the properties + * @param prop1 Property 1 + * @param prop2 Property 2 + * @param prop3 Property 3 + * @param prop4 Property 4 + */ + void sendEvent( quint64 window, const char* msg, long action, + long prop1, long prop2 = 0, long prop3 = 0, long prop4 = 0 ); + /** * @brief atomwName. Get the title of the window. *