Use xsendevent for skip_taskbar

This commit is contained in:
Ximi1970
2020-04-10 21:14:18 +02:00
parent a8dc817f1c
commit ab60704281
2 changed files with 81 additions and 82 deletions

View File

@@ -268,14 +268,12 @@ void WindowCtrlUnix::minimizeWindow( quint64 window, bool hide )
return;
}
Window win = static_cast<Window>( window );
if( hide )
{
hideWindow( win, hide );
hideWindow( window, hide );
}
XIconifyWindow( m_display, win, m_screen );
XIconifyWindow( m_display, static_cast<Window>( window ), m_screen );
XFlush( m_display );
}
@@ -290,16 +288,22 @@ void WindowCtrlUnix::normalizeWindow( quint64 window )
return;
}
hideWindow( window, false );
Window win = static_cast<Window>( 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>( 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>( 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<Atom *>( 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<unsigned char*>( &prop_skip_taskbar ), 1 );
}
else
if( !set && present )
{
/*
* Remove the atom
*/
XChangeProperty( m_display, win, prop, XA_ATOM, format, PropModeReplace,
reinterpret_cast<unsigned char*>( new_atom_list ), static_cast<int>( len - 1 ) );
}
/*
* Cleanup
*/
if( new_atom_list )
{
delete [] new_atom_list;
}
sendEvent( window,
"_NET_WM_STATE",
_NET_WM_STATE_ADD,
static_cast<long>( 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<long>( 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>( 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<long>( 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>( 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
*/

View File

@@ -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.
*