mirror of
https://github.com/Ximi1970/systray-x.git
synced 2026-05-06 23:55:39 +02:00
Move x11 functions to a separate lib
This commit is contained in:
@@ -75,6 +75,20 @@ unix:!macx: {
|
||||
QMAKE_LFLAGS += $(RPM_OPT_FLAGS)
|
||||
# QMAKE_LFLAGS += -static-libgcc -static-libstdc++
|
||||
|
||||
#
|
||||
# Add local ncludes
|
||||
#
|
||||
QMAKE_CFLAGS += -I$${_PRO_FILE_PWD_}/../SysTray-X-lib-x11
|
||||
QMAKE_CXXFLAGS += -I$${_PRO_FILE_PWD_}/../SysTray-X-lib-x11
|
||||
|
||||
#
|
||||
# Add local libs
|
||||
#
|
||||
LIBS += -L../SysTray-X-lib-x11 -lSysTray-X-x11
|
||||
|
||||
#
|
||||
# Add system libs
|
||||
#
|
||||
LIBS += -lX11
|
||||
|
||||
#
|
||||
@@ -162,6 +176,7 @@ SOURCES += \
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
debug.h \
|
||||
systrayxlink.h \
|
||||
systrayxicon.h \
|
||||
systrayx.h \
|
||||
|
||||
9
app/SysTray-X/SysTray-X-app/debug.h
Normal file
9
app/SysTray-X/SysTray-X-app/debug.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
/*
|
||||
* show all actions (normalize, minimize, hide, show/hide)
|
||||
*/
|
||||
//#define DEBUG_DISPLAY_ACTIONS
|
||||
|
||||
#endif // DEBUG_H
|
||||
@@ -2,14 +2,21 @@
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
|
||||
/*
|
||||
* Local includes
|
||||
*/
|
||||
#include "debug.h"
|
||||
#include "systray-x-lib-x11.h"
|
||||
|
||||
/*
|
||||
* System includes
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
/*
|
||||
* Qt includes
|
||||
*/
|
||||
#include <QFileInfo>
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
@@ -26,7 +33,7 @@ WindowCtrlUnix::WindowCtrlUnix( QObject *parent ) : QObject( parent )
|
||||
/*
|
||||
* Get the base display and window
|
||||
*/
|
||||
m_display = XOpenDisplay( NULL );
|
||||
m_display = OpenDisplay();
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +107,7 @@ QString WindowCtrlUnix::getProcessName( qint64 pid ) const
|
||||
*/
|
||||
bool WindowCtrlUnix::findWindow( const QString& title )
|
||||
{
|
||||
QList< WindowItem > windows = listXWindows( m_display, XDefaultRootWindow( m_display ) );
|
||||
QList< WindowItem > windows = listXWindows( m_display, GetDefaultRootWindow( m_display ) );
|
||||
|
||||
m_tb_windows = QList< quint64 >();
|
||||
for( int i = 0 ; i < windows.length() ; ++i )
|
||||
@@ -108,16 +115,16 @@ bool WindowCtrlUnix::findWindow( const QString& title )
|
||||
WindowItem win = windows.at( i );
|
||||
|
||||
char *name = nullptr;
|
||||
if( XFetchName( m_display, win.window, &name ) > 0 ) {
|
||||
if( FetchName( m_display, win.window, &name ) > 0 ) {
|
||||
QString win_name( name );
|
||||
|
||||
XFree( name );
|
||||
Free( name );
|
||||
|
||||
if( win_name.contains( title, Qt::CaseInsensitive ) ) {
|
||||
/*
|
||||
* Store the XID
|
||||
*/
|
||||
m_tb_windows.append( static_cast<quint64>( win.window ) );
|
||||
m_tb_windows.append( win.window );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,43 +143,35 @@ bool WindowCtrlUnix::findWindow( const QString& title )
|
||||
*/
|
||||
void WindowCtrlUnix::findWindows( qint64 pid )
|
||||
{
|
||||
QList< WindowItem > windows = listXWindows( m_display, XDefaultRootWindow( m_display ) );
|
||||
|
||||
// Get the PID property atom.
|
||||
Atom atom_PID = XInternAtom( m_display, "_NET_WM_PID", True );
|
||||
if( atom_PID == None )
|
||||
{
|
||||
return;
|
||||
}
|
||||
QList< WindowItem > windows = listXWindows( m_display, GetDefaultRootWindow( m_display ) );
|
||||
|
||||
m_tb_windows = QList< quint64 >();
|
||||
for( int i = 0 ; i < windows.length() ; ++i )
|
||||
{
|
||||
WindowItem win = windows.at( i );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long nItems;
|
||||
unsigned long bytesAfter;
|
||||
quint32 n_propPID;
|
||||
void* propPID = GetWindowProperty( m_display, win.window, "_NET_WM_PID", &n_propPID );
|
||||
|
||||
unsigned char* propPID = nullptr;
|
||||
if( Success == XGetWindowProperty( m_display, win.window, atom_PID, 0, 1, False, XA_CARDINAL,
|
||||
&type, &format, &nItems, &bytesAfter, &propPID ) )
|
||||
if( propPID != nullptr )
|
||||
{
|
||||
if( propPID != nullptr )
|
||||
if( pid == *((reinterpret_cast<qint64 *>( propPID ) ) ) )
|
||||
{
|
||||
if( pid == *((reinterpret_cast<qint64 *>( propPID ) ) ) )
|
||||
{
|
||||
long state = atomWmState( m_display, win.window );
|
||||
quint32 n_state;
|
||||
void* state = GetWindowProperty( m_display, win.window, "WM_STATE", &n_state );
|
||||
|
||||
if( state > 0 )
|
||||
if( state != nullptr )
|
||||
{
|
||||
if( *reinterpret_cast<long *>( state ) > 0 )
|
||||
{
|
||||
m_tb_windows.append( win.window );
|
||||
}
|
||||
}
|
||||
|
||||
XFree( propPID );
|
||||
Free( state );
|
||||
}
|
||||
}
|
||||
|
||||
Free( propPID );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +183,27 @@ void WindowCtrlUnix::findWindows( qint64 pid )
|
||||
m_tb_window_states = QList< Preferences::WindowState >();
|
||||
for( int i = 0 ; i< m_tb_windows.length() ; ++i )
|
||||
{
|
||||
QStringList atom_list = atomNetWmState( m_display, m_tb_windows.at( i ) );
|
||||
QStringList atom_list;
|
||||
|
||||
quint32 n_states;
|
||||
void* states = GetWindowProperty( m_display, m_tb_windows.at( i ), "_NET_WM_STATE", &n_states );
|
||||
|
||||
if( states != nullptr )
|
||||
{
|
||||
for( quint32 i = 0; i < n_states ; ++i )
|
||||
{
|
||||
char* atom_name = GetAtomName( m_display, reinterpret_cast<long *>( states )[ i ] );
|
||||
|
||||
atom_list.append( atom_name );
|
||||
|
||||
if( atom_name )
|
||||
{
|
||||
Free( atom_name );
|
||||
}
|
||||
}
|
||||
|
||||
Free( states );
|
||||
}
|
||||
|
||||
// emit signalConsole( QString( "WinID %1, Atoms: %2" ).arg( m_tb_windows.at( i ) ).arg( atom_list.join(",") ) );
|
||||
|
||||
@@ -214,17 +233,17 @@ const QList< Preferences::WindowState >& WindowCtrlUnix::getWindowStates() co
|
||||
*/
|
||||
void WindowCtrlUnix::displayWindowElements( const QString& title )
|
||||
{
|
||||
QList< WindowItem > windows = listXWindows( m_display, XDefaultRootWindow( m_display ) );
|
||||
QList< WindowItem > windows = listXWindows( m_display, GetDefaultRootWindow( m_display ) );
|
||||
|
||||
for( int i = 0 ; i < windows.length() ; ++i )
|
||||
{
|
||||
WindowItem win = windows.at( i );
|
||||
|
||||
char *name = nullptr;
|
||||
if( XFetchName( m_display, win.window, &name ) > 0 ) {
|
||||
if( FetchName( m_display, win.window, &name ) > 0 ) {
|
||||
QString win_name( name );
|
||||
|
||||
XFree( name );
|
||||
Free( name );
|
||||
|
||||
if( win_name.contains( title, Qt::CaseInsensitive ) ) {
|
||||
|
||||
@@ -242,16 +261,68 @@ void WindowCtrlUnix::displayWindowElements( const QString& title )
|
||||
*/
|
||||
void WindowCtrlUnix::displayWindowElements( quint64 window )
|
||||
{
|
||||
QString name = atomName( m_display, window );
|
||||
QString name;
|
||||
|
||||
quint32 n_name;
|
||||
void* name_ptr = GetWindowProperty( m_display, window, "_NET_WM_NAME", &n_name );
|
||||
|
||||
if( name_ptr != nullptr )
|
||||
{
|
||||
name = QString( reinterpret_cast<char*>( name_ptr ) );
|
||||
|
||||
Free( name_ptr );
|
||||
}
|
||||
|
||||
emit signalConsole( QString( "Atom name: %1" ).arg( name ) );
|
||||
|
||||
QStringList types = atomWindowType( m_display, window );
|
||||
QStringList types;
|
||||
|
||||
quint32 n_types;
|
||||
void* types_ptr = GetWindowProperty( m_display, window, "_NET_WM_WINDOW_TYPE", &n_types );
|
||||
|
||||
if( types_ptr != nullptr )
|
||||
{
|
||||
for( quint32 i = 0; i < n_types; ++i )
|
||||
{
|
||||
char* type_name = GetAtomName( m_display, reinterpret_cast<long *>( types_ptr )[ i ] );
|
||||
|
||||
types.append( type_name );
|
||||
|
||||
if( type_name )
|
||||
{
|
||||
Free( type_name );
|
||||
}
|
||||
}
|
||||
|
||||
Free( types_ptr );
|
||||
}
|
||||
|
||||
for( int i = 0 ; i < types.length() ; ++i )
|
||||
{
|
||||
emit signalConsole( QString( "Atom type: %1" ).arg( types.at( i ) ) );
|
||||
}
|
||||
|
||||
QStringList states = atomNetWmState( m_display, window );
|
||||
QStringList states;
|
||||
|
||||
quint32 n_states;
|
||||
void* states_ptr = GetWindowProperty( m_display,window, "_NET_WM_STATE", &n_states );
|
||||
|
||||
if( states_ptr != nullptr )
|
||||
{
|
||||
for( quint32 i = 0; i < n_states ; ++i )
|
||||
{
|
||||
char* atom_name = GetAtomName( m_display, reinterpret_cast<long *>( states_ptr )[ i ] );
|
||||
|
||||
states.append( atom_name );
|
||||
|
||||
if( atom_name )
|
||||
{
|
||||
Free( atom_name );
|
||||
}
|
||||
}
|
||||
|
||||
Free( states_ptr );
|
||||
}
|
||||
|
||||
bool max_vert = false;
|
||||
bool max_horz = false;
|
||||
@@ -329,17 +400,28 @@ void WindowCtrlUnix::updatePositions()
|
||||
{
|
||||
quint64 window = m_tb_windows.at( i );
|
||||
|
||||
// Get border / title bar sizes
|
||||
QMargins margin = atomFrameExtents( m_display, window );
|
||||
/*
|
||||
* Get border / title bar sizes
|
||||
*/
|
||||
long left;
|
||||
long top;
|
||||
long right;
|
||||
long bottom;
|
||||
GetWindowFrameExtensions( m_display, window, &left, &top, &right, &bottom );
|
||||
|
||||
int x, y;
|
||||
Window child;
|
||||
XWindowAttributes xwa;
|
||||
Window win = static_cast<Window>( window );
|
||||
XTranslateCoordinates( m_display, win, XDefaultRootWindow( m_display ), 0, 0, &x, &y, &child );
|
||||
XGetWindowAttributes( m_display, win, &xwa );
|
||||
/*
|
||||
* Get the position
|
||||
*/
|
||||
long x;
|
||||
long y;
|
||||
GetWindowPosition( m_display, window, &x, &y );
|
||||
|
||||
positions.append( QPoint( x - xwa.x - margin.left(), y - xwa.y - margin.top() ) );
|
||||
/*
|
||||
* Add to the list
|
||||
*/
|
||||
positions.append( QPoint( x - left, y - top ) );
|
||||
|
||||
// emit signalConsole( QString( "Update pos: %1, %2" ).arg( x - left ).arg( y - top ) );
|
||||
}
|
||||
|
||||
if( m_tb_windows_pos != positions )
|
||||
@@ -354,57 +436,55 @@ void WindowCtrlUnix::updatePositions()
|
||||
/*
|
||||
* Minimize a window
|
||||
*/
|
||||
void WindowCtrlUnix::minimizeWindow( quint64 window, int hide )
|
||||
void WindowCtrlUnix::minimizeWindow( quint64 window, bool hide )
|
||||
{
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( "Minimize" );
|
||||
#endif
|
||||
|
||||
if( !isThunderbird( getPpid() ) )
|
||||
{
|
||||
emit signalConsole( "Minimize terminated" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove from taskbar
|
||||
*/
|
||||
hideWindow( window, hide );
|
||||
|
||||
/*
|
||||
* Minimize the window
|
||||
*/
|
||||
XWindowAttributes xwa;
|
||||
XGetWindowAttributes( m_display, window, &xwa );
|
||||
int screen = XScreenNumberOfScreen( xwa.screen );
|
||||
|
||||
XIconifyWindow( m_display, window, screen );
|
||||
IconifyWindow( m_display, window );
|
||||
|
||||
/*
|
||||
* Flush the pipes
|
||||
*/
|
||||
XFlush( m_display );
|
||||
Flush( m_display );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hide window to system tray
|
||||
*/
|
||||
void WindowCtrlUnix::hideWindow( quint64 window, int set )
|
||||
void WindowCtrlUnix::hideWindow( quint64 window, bool hide )
|
||||
{
|
||||
emit signalConsole( "Hide" );
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( QString( "Hide: %1").arg(hide) );
|
||||
#endif
|
||||
|
||||
switch( m_minimize_type )
|
||||
if( hide )
|
||||
{
|
||||
case Preferences::PREF_MINIMIZE_METHOD_1:
|
||||
{
|
||||
emit signalConsole( "Hide 1" );
|
||||
SendEvent( m_display, window, "_NET_WM_STATE", _NET_WM_STATE_ADD, _ATOM_SKIP_TASKBAR );
|
||||
SendEvent( m_display, window, "_NET_WM_STATE", _NET_WM_STATE_ADD, _ATOM_SKIP_PAGER );
|
||||
|
||||
hideWindowEvent( window, set );
|
||||
break;
|
||||
}
|
||||
// Sync( m_display );
|
||||
|
||||
default:
|
||||
{
|
||||
emit signalConsole( "Hide default" );
|
||||
break;
|
||||
}
|
||||
// ChangeWindowTypeProperty( m_display, window, "_NET_WM_WINDOW_TYPE_DOCK" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// ChangeWindowTypeProperty( m_display, window, "_NET_WM_WINDOW_TYPE_NORMAL" );
|
||||
|
||||
// Sync( m_display );
|
||||
|
||||
SendEvent( m_display, window, "_NET_WM_STATE", _NET_WM_STATE_REMOVE, _ATOM_SKIP_TASKBAR );
|
||||
SendEvent( m_display, window, "_NET_WM_STATE", _NET_WM_STATE_REMOVE, _ATOM_SKIP_PAGER );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,22 +494,17 @@ void WindowCtrlUnix::hideWindow( quint64 window, int set )
|
||||
*/
|
||||
void WindowCtrlUnix::normalizeWindow( quint64 window )
|
||||
{
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( "Normalize" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get the current desktop
|
||||
*/
|
||||
int current_desktop = 0;
|
||||
|
||||
/*
|
||||
XWindowAttributes xwa;
|
||||
XGetWindowAttributes( m_display, window, &xwa);
|
||||
int screen = XScreenNumberOfScreen( xwa.screen );
|
||||
Window root = XRootWindow( m_display, screen );
|
||||
*/
|
||||
|
||||
quint32 n_current_desktop;
|
||||
long* current_desktop_ptr = (long*)GetWindowProperty( XDefaultRootWindow( m_display ), "_NET_CURRENT_DESKTOP", &n_current_desktop );
|
||||
long* current_desktop_ptr = (long*)GetWindowProperty( m_display, 0, "_NET_CURRENT_DESKTOP", &n_current_desktop );
|
||||
|
||||
if( current_desktop_ptr != nullptr )
|
||||
{
|
||||
@@ -441,199 +516,44 @@ void WindowCtrlUnix::normalizeWindow( quint64 window )
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
XFree( current_desktop_ptr );
|
||||
Free( current_desktop_ptr );
|
||||
|
||||
/*
|
||||
* Set the desktop for the window
|
||||
*/
|
||||
XEvent event_desktop;
|
||||
event_desktop.xclient.type = ClientMessage;
|
||||
event_desktop.xclient.serial = 0;
|
||||
event_desktop.xclient.send_event = True;
|
||||
event_desktop.xclient.message_type = XInternAtom( m_display, "_NET_WM_DESKTOP", True );
|
||||
event_desktop.xclient.window = window;
|
||||
event_desktop.xclient.format = 32;
|
||||
event_desktop.xclient.data.l[0] = current_desktop;
|
||||
event_desktop.xclient.data.l[1] = 1;
|
||||
|
||||
XSendEvent( m_display, XDefaultRootWindow( m_display ), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&event_desktop );
|
||||
SendEvent( m_display, window, "_NET_WM_DESKTOP", current_desktop, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Show window on taskbar
|
||||
*/
|
||||
XEvent event_taskbar;
|
||||
event_taskbar.xclient.type = ClientMessage;
|
||||
event_taskbar.xclient.serial = 0;
|
||||
event_taskbar.xclient.send_event = True;
|
||||
event_taskbar.xclient.message_type = XInternAtom( m_display, "_NET_WM_STATE", False );
|
||||
event_taskbar.xclient.window = window;
|
||||
event_taskbar.xclient.format = 32;
|
||||
event_taskbar.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
|
||||
event_taskbar.xclient.data.l[1] = XInternAtom( m_display, "_NET_WM_STATE_SKIP_TASKBAR", False );
|
||||
|
||||
XSendEvent( m_display, XDefaultRootWindow( m_display ), False, SubstructureRedirectMask | SubstructureNotifyMask, &event_taskbar );
|
||||
|
||||
/*
|
||||
* Normalize
|
||||
*/
|
||||
XEvent event_normalize;
|
||||
event_normalize.xclient.type = ClientMessage;
|
||||
event_normalize.xclient.serial = 0;
|
||||
event_normalize.xclient.send_event = True;
|
||||
event_normalize.xclient.message_type = XInternAtom( m_display, "_NET_ACTIVE_WINDOW", False );
|
||||
event_normalize.xclient.window = window;
|
||||
event_normalize.xclient.format = 32;
|
||||
|
||||
XSendEvent( m_display, XDefaultRootWindow( m_display ), False, SubstructureRedirectMask | SubstructureNotifyMask, &event_normalize );
|
||||
|
||||
/*
|
||||
* Raise the window to the top
|
||||
*/
|
||||
XMapRaised( m_display, window );
|
||||
|
||||
/*
|
||||
* Flush the pipes
|
||||
*/
|
||||
XFlush( m_display );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef WORKS
|
||||
|
||||
|
||||
/*
|
||||
* Normalize a window
|
||||
*/
|
||||
void WindowCtrlUnix::normalizeWindow( quint64 window )
|
||||
{
|
||||
emit signalConsole( "Normalize" );
|
||||
|
||||
if( !isThunderbird( getPpid() ) )
|
||||
{
|
||||
emit signalConsole( "Normalize terminated" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current desktop
|
||||
*/
|
||||
int current_desktop = 0;
|
||||
|
||||
/*
|
||||
XWindowAttributes xwa;
|
||||
XGetWindowAttributes( m_display, window, &xwa);
|
||||
int screen = XScreenNumberOfScreen( xwa.screen );
|
||||
Window root = XRootWindow( m_display, screen );
|
||||
*/
|
||||
|
||||
quint32 n_current_desktop;
|
||||
long* current_desktop_ptr = (long*)GetWindowProperty( RootWindow( m_display, m_screen ), "_NET_CURRENT_DESKTOP", &n_current_desktop );
|
||||
|
||||
if( current_desktop_ptr != nullptr )
|
||||
{
|
||||
emit signalConsole( QString( "Pre Desktop %1" ).arg( *current_desktop_ptr ) );
|
||||
|
||||
/*
|
||||
* Store it
|
||||
*/
|
||||
current_desktop = *current_desktop_ptr;
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
XFree( current_desktop_ptr );
|
||||
|
||||
/*
|
||||
* Set the desktop for the window
|
||||
*/
|
||||
XClientMessageEvent event;
|
||||
event.message_type = XInternAtom( m_display, "_NET_WM_DESKTOP", True );
|
||||
event.window = window;
|
||||
event.format = 32;
|
||||
event.type = ClientMessage;
|
||||
event.data.l[0] = current_desktop;
|
||||
event.data.l[1] = 1;
|
||||
|
||||
XSendEvent( m_display, RootWindow( m_display, m_screen ), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&event );
|
||||
}
|
||||
|
||||
/*
|
||||
* Unhide the window
|
||||
*/
|
||||
hideWindow( window, false );
|
||||
|
||||
/*
|
||||
* Normalize
|
||||
*/
|
||||
SendEvent( m_display, window, "_NET_ACTIVE_WINDOW" );
|
||||
|
||||
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 = window;
|
||||
event.xclient.format = 32;
|
||||
/*
|
||||
* Raise the window to the top
|
||||
*/
|
||||
MapRaised( m_display, window );
|
||||
|
||||
XSendEvent( m_display, RootWindow( m_display, m_screen ), False, SubstructureRedirectMask | SubstructureNotifyMask, &event );
|
||||
|
||||
XMapRaised( m_display, window );
|
||||
XFlush( m_display );
|
||||
|
||||
quint32 ndesktop;
|
||||
long* desktop = (long*)GetWindowProperty( window, "_NET_WM_DESKTOP", &ndesktop );
|
||||
|
||||
if( desktop != nullptr )
|
||||
{
|
||||
emit signalConsole( QString( "Desktop %1" ).arg( *desktop ) );
|
||||
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
XFree( desktop );
|
||||
}
|
||||
/*
|
||||
* Flush the pipes
|
||||
*/
|
||||
Flush( m_display );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Delete the window
|
||||
*/
|
||||
void WindowCtrlUnix::deleteWindow( quint64 window )
|
||||
{
|
||||
if( !isThunderbird( getPpid() ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
SendEvent( m_display, window, "WM_PROTOCOLS", _ATOM_DELETE_WINDOW );
|
||||
|
||||
Window win = static_cast<Window>( window );
|
||||
|
||||
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( delete_prop == None )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
XEvent event;
|
||||
event.xclient.type = ClientMessage;
|
||||
event.xclient.window = win;
|
||||
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;
|
||||
XSendEvent( m_display, win, False, NoEventMask, &event );
|
||||
XFlush( m_display );
|
||||
Flush( m_display );
|
||||
}
|
||||
|
||||
|
||||
@@ -646,327 +566,42 @@ void WindowCtrlUnix::setPositions( QList< QPoint > window_positions )
|
||||
{
|
||||
quint64 window = m_tb_windows.at( i );
|
||||
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( QString( "Set pos: %1, %2").arg( window_positions.at( i ).x() ).arg( window_positions.at( i ).y() ) );
|
||||
#endif
|
||||
|
||||
if( i < window_positions.length() ) {
|
||||
XMoveWindow( m_display, window, window_positions.at( i ).x(), window_positions.at( i ).y() );
|
||||
MoveWindow( m_display, window, window_positions.at( i ).x(), window_positions.at( i ).y() );
|
||||
}
|
||||
}
|
||||
|
||||
XFlush( m_display );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hide window to system tray
|
||||
*/
|
||||
void WindowCtrlUnix::hideWindowEvent( quint64 window, bool set )
|
||||
{
|
||||
if( !isThunderbird( getPpid() ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( set )
|
||||
{
|
||||
emit signalConsole( "Hide remove from taskbar" );
|
||||
|
||||
sendEvent( window,
|
||||
"_NET_WM_STATE",
|
||||
_NET_WM_STATE_ADD,
|
||||
static_cast<long>( XInternAtom( m_display, "_NET_WM_STATE_SKIP_TASKBAR", False ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
emit signalConsole( "Show on taskbar" );
|
||||
|
||||
sendEvent( window,
|
||||
"_NET_WM_STATE",
|
||||
_NET_WM_STATE_REMOVE,
|
||||
static_cast<long>( XInternAtom( m_display, "_NET_WM_STATE_SKIP_TASKBAR", False ) ) );
|
||||
}
|
||||
|
||||
XFlush( m_display );
|
||||
Flush( m_display );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the X11 window list
|
||||
*/
|
||||
QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( Display *display, quint64 window, int level )
|
||||
QList< WindowCtrlUnix::WindowItem > WindowCtrlUnix::listXWindows( void* display, quint64 window, int level )
|
||||
{
|
||||
Window root;
|
||||
Window parent;
|
||||
Window *children;
|
||||
quint64 root;
|
||||
quint64 parent;
|
||||
void* children;
|
||||
unsigned int childrenCount;
|
||||
|
||||
QList< WindowItem > windows;
|
||||
if( XQueryTree( display, window, &root, &parent, &children, &childrenCount) )
|
||||
if( QueryTree( display, window, &root, &parent, &children, &childrenCount) )
|
||||
{
|
||||
for( unsigned int i = 0; i < childrenCount; ++i )
|
||||
{
|
||||
windows.append( WindowItem( children[ i ], level ) );
|
||||
windows.append( listXWindows( display, children[ i ], level + 1) );
|
||||
windows.append( WindowItem( ((quint64*)children)[ i ], level ) );
|
||||
windows.append( listXWindows( display, ((quint64*)children)[ i ], level + 1) );
|
||||
}
|
||||
|
||||
XFree( children );
|
||||
Free( children );
|
||||
}
|
||||
|
||||
return windows;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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, XDefaultRootWindow( m_display ), False, SubstructureRedirectMask | SubstructureNotifyMask, &event );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the title of the window
|
||||
*/
|
||||
QString WindowCtrlUnix::atomName( Display *display, quint64 window )
|
||||
{
|
||||
char prop_name[] = "_NET_WM_NAME";
|
||||
Atom prop = XInternAtom( display, prop_name, True );
|
||||
Atom utf8_string = XInternAtom( display, "UTF8_STRING", False );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
|
||||
QString name;
|
||||
|
||||
if( XGetWindowProperty( display, window, prop, 0, LONG_MAX, False, utf8_string,
|
||||
&type, &format, &len, &remain, &list ) == Success )
|
||||
{
|
||||
name = QString( reinterpret_cast<char*>( list ) );
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the _NET_WM_STATE of the window
|
||||
*/
|
||||
QStringList WindowCtrlUnix::atomNetWmState( Display *display, quint64 window )
|
||||
{
|
||||
char prop_name[] = "_NET_WM_STATE";
|
||||
Atom prop = XInternAtom( display, prop_name, True );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
|
||||
QStringList states;
|
||||
|
||||
// if( XGetWindowProperty( display, window, prop, 0, LONG_MAX, False, AnyPropertyType,
|
||||
// &type, &format, &len, &remain, &list ) == Success )
|
||||
if( XGetWindowProperty( display, window, prop, 0, sizeof( Atom ), False, XA_ATOM,
|
||||
&type, &format, &len, &remain, &list ) == Success )
|
||||
{
|
||||
for( unsigned long i = 0; i < len; ++i )
|
||||
{
|
||||
char* atom_name = XGetAtomName( display, reinterpret_cast<Atom *>( list )[ i ] );
|
||||
|
||||
states.append( atom_name );
|
||||
|
||||
if( atom_name )
|
||||
{
|
||||
XFree( atom_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the WM_STATE of the window
|
||||
*/
|
||||
long WindowCtrlUnix::atomWmState( Display *display, quint64 window )
|
||||
{
|
||||
char prop_name[] = "WM_STATE";
|
||||
Atom prop = XInternAtom( display, prop_name, False );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len = 0;
|
||||
unsigned char* data = nullptr;
|
||||
|
||||
long state = -1;
|
||||
if( XGetWindowProperty( display, window, prop, 0L, 2L, False, prop,
|
||||
&type, &format, &len, &remain, &data ) == Success && len )
|
||||
{
|
||||
state = *reinterpret_cast<long *>( data );
|
||||
}
|
||||
|
||||
if( data )
|
||||
{
|
||||
XFree( data );
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the type of the window
|
||||
*/
|
||||
QStringList WindowCtrlUnix::atomWindowType( Display *display, quint64 window )
|
||||
{
|
||||
char prop_name[] = "_NET_WM_WINDOW_TYPE";
|
||||
Atom prop = XInternAtom( display, prop_name, True );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
|
||||
QStringList states;
|
||||
|
||||
if( XGetWindowProperty( display, window, prop, 0, sizeof( Atom ), False, XA_ATOM,
|
||||
&type, &format, &len, &remain, &list ) == Success )
|
||||
{
|
||||
for( unsigned long i = 0; i < len; ++i )
|
||||
{
|
||||
char* atom_name = XGetAtomName( display, reinterpret_cast<Atom *>( list )[ i ] );
|
||||
|
||||
states.append( atom_name );
|
||||
|
||||
if( atom_name )
|
||||
{
|
||||
XFree( atom_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the title of the window
|
||||
*/
|
||||
QMargins WindowCtrlUnix::atomFrameExtents( Display *display, quint64 window )
|
||||
{
|
||||
char prop_name[] = "_NET_FRAME_EXTENTS";
|
||||
Atom prop = XInternAtom( display, prop_name, True );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
XEvent event;
|
||||
|
||||
// Get the frame extentions
|
||||
while( XGetWindowProperty( display, window, prop, 0, 4, False, AnyPropertyType,
|
||||
&type, &format, &len, &remain, &list ) != Success || len != 4 || remain != 0 )
|
||||
{
|
||||
XNextEvent( display, &event );
|
||||
}
|
||||
|
||||
QMargins margins;
|
||||
if( list && len == 4 )
|
||||
{
|
||||
long* extents = (long*)list;
|
||||
margins.setLeft( extents[ 0 ] );
|
||||
margins.setRight( extents[ 1 ] );
|
||||
margins.setTop( extents[ 2 ] );
|
||||
margins.setBottom( extents[ 3 ] );
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
|
||||
return margins;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the title of the window
|
||||
*/
|
||||
void* WindowCtrlUnix::GetWindowProperty( quint64 window, const char* atom, quint32* nlist )
|
||||
{
|
||||
Atom prop = XInternAtom( m_display, atom, True );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
|
||||
if( XGetWindowProperty( m_display, window, prop, 0, LONG_MAX, False, AnyPropertyType,
|
||||
&type, &format, &len, &remain, &list ) == Success && len && list )
|
||||
{
|
||||
if( nlist != nullptr )
|
||||
{
|
||||
*nlist = (quint32)len;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
if( nlist != nullptr )
|
||||
{
|
||||
*nlist = (quint32)0;
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif // Q_OS_UNIX
|
||||
|
||||
@@ -17,14 +17,11 @@
|
||||
* Qt includes
|
||||
*/
|
||||
#include <QObject>
|
||||
#include <QFileInfo>
|
||||
#include <QMargins>
|
||||
#include <QPoint>
|
||||
|
||||
/*
|
||||
* Predefines
|
||||
*/
|
||||
typedef struct _XDisplay Display;
|
||||
|
||||
/**
|
||||
* @brief The WindowCtrlUnix class.
|
||||
@@ -57,16 +54,6 @@ 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
|
||||
*/
|
||||
@@ -229,7 +216,7 @@ class WindowCtrlUnix : public QObject
|
||||
* @param window The window.
|
||||
* @param hide Hide from taskbar.
|
||||
*/
|
||||
void minimizeWindow( quint64 window, int hide );
|
||||
void minimizeWindow( quint64 window, bool hide );
|
||||
|
||||
/**
|
||||
* @brief normalizeWindow. Normalize window.
|
||||
@@ -242,9 +229,9 @@ class WindowCtrlUnix : public QObject
|
||||
* @brief hideWindow. Hide a window from the taskbar.
|
||||
*
|
||||
* @param window The window.
|
||||
* @param set The state of the window.
|
||||
* @param hide Hide state.
|
||||
*/
|
||||
void hideWindow( quint64 window, int set );
|
||||
void hideWindow( quint64 window, bool hide );
|
||||
|
||||
/**
|
||||
* @brief deleteWindow. Delete the window.
|
||||
@@ -262,22 +249,6 @@ class WindowCtrlUnix : public QObject
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief hideWindowEvent. Hide a window from the taskbar using an event message.
|
||||
*
|
||||
* @param window The window.
|
||||
* @param set The state of the window.
|
||||
*/
|
||||
void hideWindowEvent( quint64 window, bool set );
|
||||
|
||||
/**
|
||||
* @brief hideWindowAtom. Hide a window from the taskbar editing the atoms.
|
||||
*
|
||||
* @param window The window.
|
||||
* @param set The state of the window.
|
||||
*/
|
||||
void hideWindowAtom( quint64 window, bool set );
|
||||
|
||||
/**
|
||||
* @brief listXWindows. Get all the windows.
|
||||
*
|
||||
@@ -287,76 +258,7 @@ class WindowCtrlUnix : public QObject
|
||||
*
|
||||
* @return The windows list.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*
|
||||
* @return Name of the window.
|
||||
*/
|
||||
QString atomName( Display* display, quint64 window );
|
||||
|
||||
/**
|
||||
* @brief atomNetWmState. Get the _NET_WM_STATE of the window.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*
|
||||
* @return State of the window.
|
||||
*/
|
||||
QStringList atomNetWmState( Display* display, quint64 window );
|
||||
|
||||
/**
|
||||
* @brief atomWmState. Get the WM_STATE of the window.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*
|
||||
* @return State of the window.
|
||||
*/
|
||||
long atomWmState( Display* display, quint64 window );
|
||||
|
||||
/**
|
||||
* @brief atomType. Get the type of the window.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*
|
||||
* @return Type of the window.
|
||||
*/
|
||||
QStringList atomWindowType( Display* display, quint64 window );
|
||||
|
||||
/**
|
||||
* @brief atomFrameExtents. Get the frame extents of the window.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*
|
||||
* @return Type of the window.
|
||||
*/
|
||||
QMargins atomFrameExtents( Display *display, quint64 window );
|
||||
|
||||
|
||||
|
||||
void* GetWindowProperty( quint64 window, const char* atom, quint32* items = nullptr );
|
||||
|
||||
QList< WindowItem > listXWindows( void* display, quint64 window, int level = 0 );
|
||||
|
||||
signals:
|
||||
|
||||
@@ -379,7 +281,7 @@ class WindowCtrlUnix : public QObject
|
||||
/**
|
||||
* @brief m_display. Pointer to the main display.
|
||||
*/
|
||||
Display* m_display;
|
||||
void* m_display;
|
||||
|
||||
/**
|
||||
* @brief m_tb_windows. The Thunderbird windows.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include "windowctrl.h"
|
||||
|
||||
/*
|
||||
* Qt includes
|
||||
*/
|
||||
@@ -5,14 +7,14 @@
|
||||
#include <QWindow>
|
||||
#include <QCoreApplication>
|
||||
|
||||
/*
|
||||
* Main include
|
||||
*/
|
||||
#include "windowctrl.h"
|
||||
|
||||
/*
|
||||
* System includes
|
||||
*/
|
||||
|
||||
/*
|
||||
* Local includes
|
||||
*/
|
||||
#include "debug.h"
|
||||
#include "preferences.h"
|
||||
|
||||
/*
|
||||
@@ -76,7 +78,7 @@ void WindowCtrl::slotWindowTest1()
|
||||
// emit signalConsole( QString( "Found XID: %1" ).arg( getWinId() ) );
|
||||
|
||||
// findWindow( "- Mozilla Thunderbird" );
|
||||
// displayWindowElements( "- Mozilla Thunderbird" );
|
||||
displayWindowElements( "- Mozilla Thunderbird" );
|
||||
// findWindow( 4313 );
|
||||
// displayWindowElements( getWinId() );
|
||||
|
||||
@@ -148,8 +150,9 @@ void WindowCtrl::slotStartMinimizedChange()
|
||||
*/
|
||||
void WindowCtrl::slotWindowState( Preferences::WindowState state )
|
||||
{
|
||||
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( QString( "State change to: %1" ).arg( state ) );
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
|
||||
@@ -165,7 +168,9 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state )
|
||||
*/
|
||||
if( state == Preferences::STATE_MINIMIZED_ALL || state == Preferences::STATE_MINIMIZED_ALL_STARTUP )
|
||||
{
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( QString( "Minimize all" ) );
|
||||
#endif
|
||||
|
||||
if( state == Preferences::STATE_MINIMIZED_ALL )
|
||||
{
|
||||
@@ -177,7 +182,7 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state )
|
||||
*/
|
||||
for( int i = 0 ; i < win_ids.length() ; ++i )
|
||||
{
|
||||
minimizeWindow( win_ids.at( i ), getMinimizeType() );
|
||||
minimizeWindow( win_ids.at( i ), getMinimizeType() != Preferences::PREF_DEFAULT_MINIMIZE );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -188,13 +193,17 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state )
|
||||
{
|
||||
if( win_states.at( i ) == Preferences::STATE_MINIMIZED )
|
||||
{
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( QString( "Hide: %1" ).arg( win_ids.at( i ) ) );
|
||||
#endif
|
||||
|
||||
hideWindow( win_ids.at( i ), getMinimizeType() );
|
||||
hideWindow( win_ids.at( i ), getMinimizeType() != Preferences::PREF_DEFAULT_MINIMIZE );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( QString( "Unhide: %1" ).arg( win_ids.at( i ) ) );
|
||||
#endif
|
||||
|
||||
hideWindow( win_ids.at( i ), false );
|
||||
}
|
||||
@@ -235,7 +244,9 @@ void WindowCtrl::slotWindowState( Preferences::WindowState state )
|
||||
*/
|
||||
void WindowCtrl::slotShowHide()
|
||||
{
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( "Show/Hide" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update the TB windows
|
||||
@@ -262,7 +273,7 @@ void WindowCtrl::slotShowHide()
|
||||
}
|
||||
else
|
||||
{
|
||||
minimizeWindow( win_ids.at( i ), getMinimizeType() );
|
||||
minimizeWindow( win_ids.at( i ), getMinimizeType() != Preferences::PREF_DEFAULT_MINIMIZE );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,7 +284,9 @@ void WindowCtrl::slotShowHide()
|
||||
*/
|
||||
void WindowCtrl::slotClose()
|
||||
{
|
||||
#ifdef DEBUG_DISPLAY_ACTIONS
|
||||
emit signalConsole( "Close" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Update the TB windows
|
||||
|
||||
@@ -20,6 +20,6 @@ QMAKE_INCDIR_QT =
|
||||
QMAKE_LIBDIR_QT =
|
||||
|
||||
|
||||
SOURCES += systray-x-lib.cpp
|
||||
SOURCES += systray-x-lib-x11.cpp
|
||||
|
||||
HEADERS += systray-x-lib.h
|
||||
HEADERS += systray-x-lib-x11.h
|
||||
|
||||
366
app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.cpp
Normal file
366
app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.cpp
Normal file
@@ -0,0 +1,366 @@
|
||||
#include "systray-x-lib-x11.h"
|
||||
|
||||
/*
|
||||
* System includes
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* X11 includes
|
||||
*/
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
|
||||
/*
|
||||
* Open the display
|
||||
*/
|
||||
void* OpenDisplay()
|
||||
{
|
||||
return XOpenDisplay( NULL );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the default root window
|
||||
*/
|
||||
quint64 GetDefaultRootWindow( void* display )
|
||||
{
|
||||
return XDefaultRootWindow( (Display*)display );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the screen number
|
||||
*/
|
||||
int GetScreen( void* display, quint64 window )
|
||||
{
|
||||
XWindowAttributes xwa;
|
||||
XGetWindowAttributes( (Display*)display, window, &xwa );
|
||||
return XScreenNumberOfScreen( xwa.screen );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free X11 resources
|
||||
*/
|
||||
void Free( void* free )
|
||||
{
|
||||
XFree( free );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flush the event pipes.
|
||||
*/
|
||||
void Flush( void* display )
|
||||
{
|
||||
XFlush( (Display*)display );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sync the event pipes.
|
||||
*/
|
||||
void Sync( void* display )
|
||||
{
|
||||
XSync( (Display*)display, False );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Query the window tree
|
||||
*/
|
||||
int QueryTree( void* display, quint64 window, quint64* root, quint64* parent, void** children, unsigned int* childrenCount)
|
||||
{
|
||||
Window x11_root;
|
||||
Window x11_parent;
|
||||
Window* x11_children;
|
||||
unsigned int x11_childrenCount;
|
||||
|
||||
int status = XQueryTree( (Display*)display, window, &x11_root, &x11_parent, &x11_children, &x11_childrenCount );
|
||||
|
||||
*root = x11_root;
|
||||
*parent = x11_parent;
|
||||
*children = x11_children;
|
||||
*childrenCount = x11_childrenCount;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the name of a window
|
||||
*/
|
||||
int FetchName( void* display, quint64 window, char** name )
|
||||
{
|
||||
return XFetchName( (Display*)display, window, name );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Iconify the window ( minimimze )
|
||||
*/
|
||||
void IconifyWindow( void* display, quint64 window )
|
||||
{
|
||||
XIconifyWindow( (Display*)display, window, GetScreen( display, window ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Raise the window to the top
|
||||
*/
|
||||
void MapRaised( void* display, quint64 window )
|
||||
{
|
||||
XMapRaised( (Display*)display, window );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the name of the atom
|
||||
*/
|
||||
char* GetAtomName( void* display, long atom )
|
||||
{
|
||||
return XGetAtomName( (Display*)display, atom );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Change the window type
|
||||
*/
|
||||
void ChangeWindowTypeProperty( void* display, quint64 window, const char* win_type )
|
||||
{
|
||||
Display* dsp = (Display*)display;
|
||||
|
||||
Atom prop = XInternAtom( dsp, "_NET_WM_WINDOW_TYPE", True );
|
||||
Atom atom_win_type = XInternAtom( dsp, win_type, True );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
|
||||
if( XGetWindowProperty( dsp, window, prop, 0, LONG_MAX, False, AnyPropertyType,
|
||||
&type, &format, &len, &remain, &list ) == Success && len && list )
|
||||
{
|
||||
XFree( list );
|
||||
|
||||
XChangeProperty( dsp, window, prop, XA_ATOM, format, PropModeReplace,
|
||||
reinterpret_cast<unsigned char*>( &atom_win_type ), 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the title of the window
|
||||
*/
|
||||
void* GetWindowProperty( void* display, quint64 window, const char* atom, quint32* nlist )
|
||||
{
|
||||
Display* dsp = (Display*)display;
|
||||
|
||||
Window win;
|
||||
if( window == 0 )
|
||||
{
|
||||
win = XDefaultRootWindow( dsp );
|
||||
}
|
||||
else
|
||||
{
|
||||
win = window;
|
||||
}
|
||||
|
||||
Atom prop = XInternAtom( (Display*)display, atom, True );
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
|
||||
if( XGetWindowProperty( dsp, win, prop, 0, LONG_MAX, False, AnyPropertyType,
|
||||
&type, &format, &len, &remain, &list ) == Success && len && list )
|
||||
{
|
||||
if( nlist != nullptr )
|
||||
{
|
||||
*nlist = (quint32)len;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
if( nlist != nullptr )
|
||||
{
|
||||
*nlist = (quint32)0;
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send an X event
|
||||
*/
|
||||
void SendEvent( void* display, quint64 window, const char* msg_type,
|
||||
long prop0, long prop1, long prop2, long prop3 )
|
||||
{
|
||||
Display* dsp = (Display*)display;
|
||||
Window root_window = XDefaultRootWindow( dsp );
|
||||
|
||||
Atom msg_atom;
|
||||
if( strcmp( msg_type, "WM_PROTOCOLS" ) == 0 )
|
||||
{
|
||||
msg_atom = XInternAtom( dsp, msg_type, True );
|
||||
}
|
||||
else
|
||||
{
|
||||
msg_atom = XInternAtom( dsp, msg_type, False );
|
||||
}
|
||||
|
||||
XEvent event;
|
||||
event.xclient.type = ClientMessage;
|
||||
event.xclient.serial = 0;
|
||||
event.xclient.send_event = True;
|
||||
event.xclient.message_type = msg_atom;
|
||||
event.xclient.window = window;
|
||||
event.xclient.format = 32;
|
||||
|
||||
long filter = SubstructureRedirectMask | SubstructureNotifyMask;
|
||||
|
||||
if( strcmp( msg_type, "_NET_WM_STATE" ) == 0 )
|
||||
{
|
||||
event.xclient.data.l[0] = prop0;
|
||||
switch( prop1 )
|
||||
{
|
||||
case _ATOM_SKIP_TASKBAR:
|
||||
{
|
||||
event.xclient.data.l[1] = XInternAtom( dsp, "_NET_WM_STATE_SKIP_TASKBAR", False );
|
||||
break;
|
||||
}
|
||||
|
||||
case _ATOM_SKIP_PAGER:
|
||||
{
|
||||
event.xclient.data.l[1] = XInternAtom( dsp, "_NET_WM_STATE_SKIP_PAGER", False );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if( strcmp( msg_type, "WM_PROTOCOLS" ) == 0 )
|
||||
{
|
||||
switch( prop0 )
|
||||
{
|
||||
case _ATOM_DELETE_WINDOW:
|
||||
{
|
||||
event.xclient.data.l[0] = XInternAtom( dsp, "WM_DELETE_WINDOW", False );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.xclient.data.l[1] = CurrentTime;
|
||||
|
||||
root_window = window;
|
||||
filter = NoEventMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
event.xclient.data.l[0] = prop0;
|
||||
event.xclient.data.l[1] = prop1;
|
||||
event.xclient.data.l[2] = prop2;
|
||||
event.xclient.data.l[3] = prop3;
|
||||
}
|
||||
|
||||
XSendEvent( dsp, root_window, False, filter, &event );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the frame extensions
|
||||
*/
|
||||
void GetWindowFrameExtensions( void *display, quint64 window, long* left, long* top, long* right, long* bottom )
|
||||
{
|
||||
Display* dsp = (Display*)display;
|
||||
|
||||
char prop_name[] = "_NET_FRAME_EXTENTS";
|
||||
Atom prop = XInternAtom( dsp, prop_name, True );
|
||||
|
||||
/*
|
||||
* Reset the margins
|
||||
*/
|
||||
*left = 0;
|
||||
*top = 0;
|
||||
*right = 0;
|
||||
*bottom = 0;
|
||||
|
||||
/*
|
||||
* Get the frame extentions
|
||||
*/
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long remain;
|
||||
unsigned long len;
|
||||
unsigned char* list = nullptr;
|
||||
XEvent event;
|
||||
|
||||
while( XGetWindowProperty( dsp, window, prop, 0, 4, False, AnyPropertyType,
|
||||
&type, &format, &len, &remain, &list ) != Success || len != 4 || remain != 0 )
|
||||
{
|
||||
XNextEvent( dsp, &event );
|
||||
}
|
||||
|
||||
if( list && len == 4 )
|
||||
{
|
||||
long* extents = (long*)list;
|
||||
*left = extents[ 0 ];
|
||||
*right = extents[ 1 ];
|
||||
*top = extents[ 2 ];
|
||||
*bottom = extents[ 3 ];
|
||||
}
|
||||
|
||||
if( list )
|
||||
{
|
||||
XFree( list );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the window position
|
||||
*/
|
||||
void GetWindowPosition( void* display, quint64 window, long* pos_x, long* pos_y )
|
||||
{
|
||||
Display* dsp = (Display*)display;
|
||||
|
||||
int x, y;
|
||||
Window child;
|
||||
XWindowAttributes xwa;
|
||||
XTranslateCoordinates( dsp, window, XDefaultRootWindow( dsp ), 0, 0, &x, &y, &child );
|
||||
XGetWindowAttributes( dsp, window, &xwa );
|
||||
|
||||
*pos_x = x - xwa.x;
|
||||
*pos_y = y - xwa.y;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the window position
|
||||
*/
|
||||
void MoveWindow( void* display, quint64 window, int x, int y )
|
||||
{
|
||||
XMoveWindow( (Display*)display, window, x, y );
|
||||
}
|
||||
207
app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.h
Normal file
207
app/SysTray-X/SysTray-X-lib-x11/systray-x-lib-x11.h
Normal file
@@ -0,0 +1,207 @@
|
||||
#ifndef SYSTRAY_X_LIB_H
|
||||
#define SYSTRAY_X_LIB_H
|
||||
|
||||
/*
|
||||
* System includes
|
||||
*/
|
||||
//#include <sys/types.h>
|
||||
|
||||
|
||||
typedef unsigned int quint32; /* 32 bit unsigned */
|
||||
typedef unsigned long long quint64; /* 64 bit unsigned */
|
||||
|
||||
|
||||
/*
|
||||
* State actions
|
||||
*/
|
||||
enum StateActions
|
||||
{
|
||||
_NET_WM_STATE_REMOVE = 0,
|
||||
_NET_WM_STATE_ADD,
|
||||
_NET_WM_STATE_TOGGLE
|
||||
};
|
||||
|
||||
enum StateAtoms
|
||||
{
|
||||
_ATOM_SKIP_TASKBAR = 0,
|
||||
_ATOM_SKIP_PAGER
|
||||
};
|
||||
|
||||
|
||||
enum ProtocolAtoms
|
||||
{
|
||||
_ATOM_DELETE_WINDOW = 0
|
||||
};
|
||||
|
||||
struct Point {
|
||||
long x;
|
||||
long y;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief OpenDisplay. Open the display.
|
||||
*
|
||||
* @return Pointer to the display struct.
|
||||
*/
|
||||
void* OpenDisplay();
|
||||
|
||||
/**
|
||||
* @brief GetDefaultRootWindow
|
||||
*
|
||||
* @param display The display
|
||||
*
|
||||
* @return The root window.
|
||||
*/
|
||||
quint64 GetDefaultRootWindow( void* display );
|
||||
|
||||
/**
|
||||
* @brief GetScreen. Get the screen number.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*
|
||||
* @return The screen number.
|
||||
*/
|
||||
int GetScreen( void* display, quint64 window );
|
||||
|
||||
/**
|
||||
* @brief Free. Free allocated X11 resources.
|
||||
*
|
||||
* @param free Pointer to the resource
|
||||
*/
|
||||
void Free( void* free );
|
||||
|
||||
/**
|
||||
* @brief Flush. Flush the event pipes.
|
||||
*
|
||||
* @param display The display
|
||||
*/
|
||||
void Flush( void* display );
|
||||
|
||||
/**
|
||||
* @brief Sync
|
||||
*
|
||||
* @param display The display
|
||||
*/
|
||||
void Sync( void* display );
|
||||
|
||||
/**
|
||||
* @brief QueryTree. Query te window tree.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param root The root window
|
||||
* @param parent The parent window
|
||||
* @param children The list of children
|
||||
* @param childrenCount The number of children
|
||||
*
|
||||
* @return The status of the query.
|
||||
*/
|
||||
int QueryTree( void* display, quint64 window, quint64* root, quint64* parent, void** children, unsigned int* childrenCount);
|
||||
|
||||
/**
|
||||
* @brief FetchName. Get the name of the window.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param name Storage for the name
|
||||
*
|
||||
* @return The status.
|
||||
*/
|
||||
int FetchName( void* display, quint64 window, char** name );
|
||||
|
||||
/**
|
||||
* @brief IconifyWindow. Iconify the window (minimize).
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*/
|
||||
void IconifyWindow( void* display, quint64 window );
|
||||
|
||||
/**
|
||||
* @brief MapRaised. Raise the window to the top.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
*/
|
||||
void MapRaised( void* display, quint64 window );
|
||||
|
||||
/**
|
||||
* @brief GetAtomName. Get the atom name.
|
||||
*
|
||||
* @param display The display
|
||||
* @param atom The atom.
|
||||
*
|
||||
* @return The atom name.
|
||||
*/
|
||||
char* GetAtomName( void* display, long atom );
|
||||
|
||||
/**
|
||||
* @brief ChangeWindowTypeProperty. Change the window typw property.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param win_type The new window type.
|
||||
*/
|
||||
void ChangeWindowTypeProperty( void* display, quint64 window, const char* win_type );
|
||||
|
||||
/**
|
||||
* @brief GetWindowProperty. Get a window property.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param atom The atom to get
|
||||
* @param nlist Storage for the number of found properties
|
||||
*
|
||||
* @return The properties list
|
||||
*/
|
||||
void* GetWindowProperty( void* display, quint64 window, const char* atom, quint32* nlist );
|
||||
|
||||
/**
|
||||
* @brief SendEvent. Send an X event.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param msg_type The name of the atom.
|
||||
* @param prop0 The first optional property of the event
|
||||
* @param prop1 The second optional property of the event
|
||||
* @param prop2 The third optional property of the event
|
||||
* @param prop3 The fourth optional property of the event
|
||||
*/
|
||||
void SendEvent( void* display, quint64 window, const char* msg_type,
|
||||
long prop0 = 0, long prop1 = 0, long prop2 = 0, long prop3 = 0 );
|
||||
|
||||
/**
|
||||
* @brief GetWindowFrameExtensions. Get the sizes of the window frame extensions.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param left Storage for the left extension size
|
||||
* @param top Storage for the top extension size
|
||||
* @param right Storage for the right extension size
|
||||
* @param bottom Storage for the bottom extension size
|
||||
*/
|
||||
void GetWindowFrameExtensions( void *display, quint64 window, long* left, long* top, long* right, long* bottom );
|
||||
|
||||
/**
|
||||
* @brief GetWindowPosition. Get the window position.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param pos_x Storage for the x coordinate
|
||||
* @param pos_y Storage for the y coordinate
|
||||
*/
|
||||
void GetWindowPosition( void *display, quint64 window, long* pos_x, long* pos_y );
|
||||
|
||||
/**
|
||||
* @brief MoveWindow. Set the window position.
|
||||
*
|
||||
* @param display The display
|
||||
* @param window The window
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
*/
|
||||
void MoveWindow( void* display, quint64 window, int x, int y );
|
||||
|
||||
#endif // SYSTRAY_X_LIB_H
|
||||
@@ -1 +0,0 @@
|
||||
#include "systray-x-lib.h"
|
||||
@@ -1,5 +0,0 @@
|
||||
#ifndef SYSTRAY_X_LIB_H
|
||||
#define SYSTRAY_X_LIB_H
|
||||
|
||||
|
||||
#endif // SYSTRAY_X_LIB_H
|
||||
Reference in New Issue
Block a user