1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-04-21 00:12:06 +02:00

Add definitions for bringToFront. Can't test on X11 as TH crashes with database errors before I get the chance.

This commit is contained in:
Jeff Mitchell 2011-08-27 02:29:05 -04:00
parent 971cc742bb
commit dccc4e6225
5 changed files with 1198 additions and 17 deletions

View File

@ -410,7 +410,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
${LIBPORTFWD_INCLUDE_DIR}
${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb
${CMAKE_BINARY_DIR}/thirdparty/liblastfm2/src
${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/libqnetwm
)
IF( UNIX AND NOT APPLE )
@ -428,7 +428,8 @@ IF( UNIX AND NOT APPLE )
infosystem/infoplugins/unix/fdonotifyplugin.h )
IF( BUILD_GUI AND X11_FOUND )
SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${X11_LIBRARIES} )
SET( libSources ${libSources} ${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/libqnetwm/netwm.cpp )
SET( LINK_LIBRARIES ${LINK_LIBRARIES} ${X11_LIBRARIES} Xcomposite )
ENDIF()
ENDIF( UNIX AND NOT APPLE )

View File

@ -45,13 +45,16 @@
#include <QtGui/QWidget>
#ifdef Q_WS_X11
extern "C" {
#include <X11/Xlib.h>
}
#include <QtGui/QX11Info>
#include <netwm.h>
#endif
#ifdef Q_WS_WIN
#include <windows.h>
#include <windowsx.h>
#endif
#endif
#include <tomahawksettings.h>
#include "utils/logger.h"
#include "config.h"
@ -531,23 +534,41 @@ setNam( QNetworkAccessManager* nam )
i++;
QWidget *widget = widgetList.at( i );
WId winId = widget->winId();
Display *display = XOpenDisplay( NULL );
if ( !display )
{
qDebug() << Q_FUNC_INFO << "Could not find display to raise";
return;
}
widget->show();
widget->activateWindow();
widget->raise();
WId wid = widget->winId();
XRaiseWindow( display, winId );
XSetInputFocus( display, winId, RevertToNone, CurrentTime );
//widget->activateWindow();
//widget->raise();
NETWM::init();
XEvent e;
e.xclient.type = ClientMessage;
e.xclient.message_type = NETWM::NET_ACTIVE_WINDOW;
e.xclient.display = QX11Info::display();
e.xclient.window = wid;
e.xclient.format = 32;
e.xclient.data.l[0] = 2;
e.xclient.data.l[1] = QX11Info::appTime();
e.xclient.data.l[2] = 0;
e.xclient.data.l[3] = 0l;
e.xclient.data.l[4] = 0l;
XSendEvent( QX11Info::display(), RootWindow( QX11Info::display(), DefaultScreen( QX11Info::display() ) ), False, SubstructureRedirectMask | SubstructureNotifyMask, &e );
}
#elif defined(Q_WS_WIN)
void
bringToFront()
{
HWND hwndActiveWin = GetForegroundWindow();
int idActive = GetWindowThreadProcessId(hwndActiveWin, NULL);
if ( AttachThreadInput(GetCurrentThreadId(), idActive, TRUE) )
{
SetForegroundWindow( win );
SetFocus( win );
AttachThreadInput(GetCurrentThreadId(), idActive, FALSE);
}
}
#else
#ifndef Q_OS_MAC

243
thirdparty/libqnetwm/fixx11h.h vendored Normal file
View File

@ -0,0 +1,243 @@
//#ifdef don't do this, this file is supposed to be included
//#define multiple times
/* Usage:
If you get compile errors caused by X11 includes (the line
where first error appears contains word like None, Unsorted,
Below, etc.), put #include <fixx11h.h> in the .cpp file
(not .h file!) between the place where X11 headers are
included and the place where the file with compile
error is included (or the place where the compile error
in the .cpp file occurs).
This file remaps X11 #defines to const variables or
inline functions. The side effect may be that these
symbols may now refer to different variables
(e.g. if X11 #defined NoButton, after this file
is included NoButton would no longer be X11's
NoButton, but Qt::NoButton instead). At this time,
there's no conflict known that could cause problems.
The original X11 symbols are still accessible
(e.g. for None) as X::None, XNone, and also still
None, unless name lookup finds different None
first (in the current class, etc.)
Use 'Unsorted', 'Bool' and 'index' as templates.
*/
namespace X
{
// template --->
// Affects: Should be without side effects.
#ifdef Unsorted
#ifndef FIXX11H_Unsorted
#define FIXX11H_Unsorted
const int XUnsorted = Unsorted;
#undef Unsorted
const int Unsorted = XUnsorted;
#endif
#undef Unsorted
#endif
// template <---
// Affects: Should be without side effects.
#ifdef None
#ifndef FIXX11H_None
#define FIXX11H_None
const XID XNone = None;
#undef None
const XID None = XNone;
#endif
#undef None
#endif
// template --->
// Affects: Should be without side effects.
#ifdef Bool
#ifndef FIXX11H_Bool
#define FIXX11H_Bool
typedef Bool XBool;
#undef Bool
typedef XBool Bool;
#endif
#undef Bool
#endif
#ifdef FontChange
#ifndef FIXX11H_FontChange
#define FIXX11H_FontChange
const int XFontChange = FontChange;
#undef FontChange
const int FontChange = XFontChange;
#endif
#undef FontChange
#endif
// template <---
// Affects: Should be without side effects.
#ifdef KeyPress
#ifndef FIXX11H_KeyPress
#define FIXX11H_KeyPress
const int XKeyPress = KeyPress;
#undef KeyPress
const int KeyPress = XKeyPress;
#endif
#undef KeyPress
#endif
// Affects: Should be without side effects.
#ifdef KeyRelease
#ifndef FIXX11H_KeyRelease
#define FIXX11H_KeyRelease
const int XKeyRelease = KeyRelease;
#undef KeyRelease
const int KeyRelease = XKeyRelease;
#endif
#undef KeyRelease
#endif
// Affects: Should be without side effects.
#ifdef Above
#ifndef FIXX11H_Above
#define FIXX11H_Above
const int XAbove = Above;
#undef Above
const int Above = XAbove;
#endif
#undef Above
#endif
// Affects: Should be without side effects.
#ifdef Below
#ifndef FIXX11H_Below
#define FIXX11H_Below
const int XBelow = Below;
#undef Below
const int Below = XBelow;
#endif
#undef Below
#endif
// Affects: Should be without side effects.
#ifdef FocusIn
#ifndef FIXX11H_FocusIn
#define FIXX11H_FocusIn
const int XFocusIn = FocusIn;
#undef FocusIn
const int FocusIn = XFocusIn;
#endif
#undef FocusIn
#endif
// Affects: Should be without side effects.
#ifdef FocusOut
#ifndef FIXX11H_FocusOut
#define FIXX11H_FocusOut
const int XFocusOut = FocusOut;
#undef FocusOut
const int FocusOut = XFocusOut;
#endif
#undef FocusOut
#endif
// Affects: Should be without side effects.
#ifdef Always
#ifndef FIXX11H_Always
#define FIXX11H_Always
const int XAlways = Always;
#undef Always
const int Always = XAlways;
#endif
#undef Always
#endif
// Affects: Should be without side effects.
#ifdef Success
#ifndef FIXX11H_Success
#define FIXX11H_Success
const int XSuccess = Success;
#undef Success
const int Success = XSuccess;
#endif
#undef Success
#endif
// Affects: Should be without side effects.
#ifdef GrayScale
#ifndef FIXX11H_GrayScale
#define FIXX11H_GrayScale
const int XGrayScale = GrayScale;
#undef GrayScale
const int GrayScale = XGrayScale;
#endif
#undef GrayScale
#endif
// Affects: Should be without side effects.
#ifdef Status
#ifndef FIXX11H_Status
#define FIXX11H_Status
typedef Status XStatus;
#undef Status
typedef XStatus Status;
#endif
#undef Status
#endif
// Affects: Should be without side effects.
#ifdef CursorShape
#ifndef FIXX11H_CursorShape
#define FIXX11H_CursorShape
const int XCursorShape = CursorShape;
#undef CursorShape
const int CursorShape = CursorShape;
#endif
#undef CursorShape
#endif
// template --->
// Affects: Should be without side effects.
#ifdef index
#ifndef FIXX11H_index
#define FIXX11H_index
inline
char* Xindex( const char* s, int c )
{
return index( s, c );
}
#undef index
inline
char* index( const char* s, int c )
{
return Xindex( s, c );
}
#endif
#undef index
#endif
// template <---
#ifdef rindex
// Affects: Should be without side effects.
#ifndef FIXX11H_rindex
#define FIXX11H_rindex
inline
char* Xrindex( const char* s, int c )
{
return rindex( s, c );
}
#undef rindex
inline
char* rindex( const char* s, int c )
{
return Xrindex( s, c );
}
#endif
#undef rindex
#endif
}
using namespace X;

730
thirdparty/libqnetwm/netwm.cpp vendored Normal file
View File

@ -0,0 +1,730 @@
/***************************************************************************
* Copyright (C) 2010 by Dmitry 'Krasu' Baryshev *
* ksquirrel.iv@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <QX11Info>
#include <climits>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <strings.h>
#include <unistd.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xcomposite.h>
#include "netwm.h"
#define DBG(...) //fprintf(stderr, ##__VA_ARGS__)
Atom NETWM::UTF8_STRING = 0;
Atom NETWM::XROOTPMAP_ID = 0;
Atom NETWM::WM_STATE = 0;
Atom NETWM::WM_CLASS = 0;
Atom NETWM::WM_NAME = 0;
Atom NETWM::WM_DELETE_WINDOW = 0;
Atom NETWM::WM_PROTOCOLS = 0;
Atom NETWM::WM_CHANGE_STATE = 0;
Atom NETWM::WM_WINDOW_ROLE = 0;
Atom NETWM::NET_WORKAREA = 0;
Atom NETWM::NET_CLIENT_LIST = 0;
Atom NETWM::NET_CLIENT_LIST_STACKING = 0;
Atom NETWM::NET_NUMBER_OF_DESKTOPS = 0;
Atom NETWM::NET_CURRENT_DESKTOP = 0;
Atom NETWM::NET_DESKTOP_NAMES = 0;
Atom NETWM::NET_ACTIVE_WINDOW = 0;
Atom NETWM::NET_CLOSE_WINDOW = 0;
Atom NETWM::NET_SUPPORTED = 0;
Atom NETWM::NET_WM_DESKTOP = 0;
Atom NETWM::NET_SHOWING_DESKTOP = 0;
Atom NETWM::NET_WM_STATE = 0;
Atom NETWM::NET_WM_STATE_MODAL = 0;
Atom NETWM::NET_WM_STATE_STICKY = 0;
Atom NETWM::NET_WM_STATE_MAXIMIZED_VERT = 0;
Atom NETWM::NET_WM_STATE_MAXIMIZED_HORZ = 0;
Atom NETWM::NET_WM_STATE_SHADED = 0;
Atom NETWM::NET_WM_STATE_SKIP_TASKBAR = 0;
Atom NETWM::NET_WM_STATE_SKIP_PAGER = 0;
Atom NETWM::NET_WM_STATE_HIDDEN = 0;
Atom NETWM::NET_WM_STATE_FULLSCREEN = 0;
Atom NETWM::NET_WM_STATE_ABOVE = 0;
Atom NETWM::NET_WM_STATE_BELOW = 0;
Atom NETWM::NET_WM_STATE_STAYS_ON_TOP = 0;
Atom NETWM::NET_WM_STATE_STAYS_ON_BOTTOM = 0;
Atom NETWM::NET_WM_STATE_DEMANDS_ATTENTION = 0;
Atom NETWM::NET_WM_WINDOW_TYPE = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_DESKTOP = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_DOCK = 0;
Atom NETWM::MODERRO_WINDOW_TYPE_DOCK = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_TOOLBAR = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_MENU = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_UTILITY = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_SPLASH = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_DIALOG = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_DROPDOWN_MENU = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_POPUP_MENU = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_TOOLTIP = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_NOTIFICATION = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_COMBO = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_DND = 0;
Atom NETWM::NET_WM_WINDOW_TYPE_NORMAL = 0;
Atom NETWM::NET_WM_WINDOW_OPACITY = 0;
Atom NETWM::NET_WM_NAME = 0;
Atom NETWM::NET_WM_VISIBLE_NAME = 0;
Atom NETWM::NET_WM_STRUT = 0;
Atom NETWM::NET_WM_STRUT_PARTIAL = 0;
Atom NETWM::NET_WM_ICON = 0;
Atom NETWM::NET_WM_PID = 0;
NETWM::net_wm_state::net_wm_state()
: modal(0), sticky(0), maximized_vert(0),
maximized_horz(0), shaded(0), skip_taskbar(0),
skip_pager(0), hidden(0), fullscreen(0),
above(0), below(0), stays_on_top(0), stays_on_bottom(0),
demands_attention(0), valid(false)
{}
NETWM::net_wm_window_type::net_wm_window_type()
: desktop(0), dock(0), toolbar(0),
menu(0), utility(0), splash(0), dialog(0),
dropdown(0), popup(0), tooltip(0), notification(0),
combo(0), dnd(0), normal(0), valid(false)
{}
/**********************************************************/
void NETWM::init()
{
Display *dpy = QX11Info::display();
UTF8_STRING = XInternAtom(dpy, "UTF8_STRING", False);
XROOTPMAP_ID = XInternAtom(dpy, "_XROOTPMAP_ID", False);
WM_STATE = XInternAtom(dpy, "WM_STATE", False);
WM_CLASS = XInternAtom(dpy, "WM_CLASS", False);
WM_NAME = XInternAtom(dpy, "WM_NAME", False);
WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
WM_CHANGE_STATE = XInternAtom(dpy, "WM_CHANGE_STATE", False);
WM_WINDOW_ROLE = XInternAtom(dpy, "WM_WINDOW_ROLE", False);
WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
NET_WORKAREA = XInternAtom(dpy, "_NET_WORKAREA", False);
NET_CLIENT_LIST = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
NET_CLIENT_LIST_STACKING = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
NET_NUMBER_OF_DESKTOPS = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
NET_CURRENT_DESKTOP = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
NET_DESKTOP_NAMES = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False);
NET_ACTIVE_WINDOW = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
NET_CLOSE_WINDOW = XInternAtom(dpy, "_NET_CLOSE_WINDOW", False);
NET_SUPPORTED = XInternAtom(dpy, "_NET_SUPPORTED", False);
NET_WM_DESKTOP = XInternAtom(dpy, "_NET_WM_DESKTOP", False);
NET_SHOWING_DESKTOP = XInternAtom(dpy, "_NET_SHOWING_DESKTOP", False);
NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False);
NET_WM_STATE_MODAL = XInternAtom(dpy, "_NET_WM_STATE_MODAL", False);
NET_WM_STATE_STICKY = XInternAtom(dpy, "_NET_WM_STATE_STICKY", False);
NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_VERT", False);
NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
NET_WM_STATE_SHADED = XInternAtom(dpy, "_NET_WM_STATE_SHADED", False);
NET_WM_STATE_SKIP_TASKBAR = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR", False);
NET_WM_STATE_SKIP_PAGER = XInternAtom(dpy, "_NET_WM_STATE_SKIP_PAGER", False);
NET_WM_STATE_HIDDEN = XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
NET_WM_STATE_ABOVE = XInternAtom(dpy, "_NET_WM_STATE_ABOVE", False);
NET_WM_STATE_BELOW = XInternAtom(dpy, "_NET_WM_STATE_BELOW", False);
NET_WM_STATE_STAYS_ON_TOP = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_TOP", False);
NET_WM_STATE_STAYS_ON_BOTTOM = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_BOTTOM", False);
NET_WM_STATE_DEMANDS_ATTENTION = XInternAtom(dpy, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
NET_WM_WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
NET_WM_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
MODERRO_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_MODERRO_WINDOW_TYPE_DOCK", False);
NET_WM_WINDOW_TYPE_TOOLBAR = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
NET_WM_WINDOW_TYPE_MENU = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_MENU", False);
NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_UTILITY", False);
NET_WM_WINDOW_TYPE_SPLASH = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_SPLASH", False);
NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
NET_WM_WINDOW_TYPE_POPUP_MENU = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
NET_WM_WINDOW_TYPE_TOOLTIP = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_TOOLTIP", False);
NET_WM_WINDOW_TYPE_NOTIFICATION = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
NET_WM_WINDOW_TYPE_COMBO = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_COMBO", False);
NET_WM_WINDOW_TYPE_DND = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DND", False);
NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL", False);
NET_WM_WINDOW_OPACITY = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
NET_WM_NAME = XInternAtom(dpy, "_NET_WM_NAME", False);
NET_WM_VISIBLE_NAME = XInternAtom(dpy, "_NET_WM_VISIBLE_NAME", False);
NET_WM_STRUT = XInternAtom(dpy, "_NET_WM_STRUT", False);
NET_WM_STRUT_PARTIAL = XInternAtom(dpy, "_NET_WM_STRUT_PARTIAL", False);
NET_WM_ICON = XInternAtom(dpy, "_NET_WM_ICON", False);
NET_WM_PID = XInternAtom(dpy, "_NET_WM_PID", False);
}
int NETWM::setProperty(Window window, Atom atom, long offset, uchar *data, int nelem)
{
NETWM::checkInit();
return XChangeProperty(QX11Info::display(), window, atom, offset, 32, PropModeReplace, data, nelem);
}
int NETWM::setPropertySkipTaskbar(Window window)
{
NETWM::checkInit();
Atom state[3];
state[0] = NETWM::NET_WM_STATE_SKIP_PAGER;
state[1] = NETWM::NET_WM_STATE_SKIP_TASKBAR;
state[2] = NETWM::NET_WM_STATE_STICKY;
return NETWM::setProperty(window, NETWM::NET_WM_STATE, XA_ATOM, (uchar *)&state, 3);
}
int NETWM::setPropertyOnTop(Window window)
{
NETWM::checkInit();
Atom state[2];
state[0] = NETWM::NET_WM_STATE_ABOVE;
state[1] = NETWM::NET_WM_STATE_STAYS_ON_TOP;
return NETWM::setProperty(window, NETWM::NET_WM_STATE, XA_ATOM, (uchar *)&state, 2);
}
void* NETWM::property(Window win, Atom prop, Atom type, int *nitems, bool *ok)
{
NETWM::checkInit();
Atom type_ret;
int format_ret;
unsigned long items_ret;
unsigned long after_ret;
unsigned char *prop_data = 0;
if(XGetWindowProperty(QX11Info::display(),
win,
prop,
0,
0x7fffffff,
False,
type,
&type_ret,
&format_ret,
&items_ret,
&after_ret,
&prop_data) != Success)
{
if(ok)
*ok = false;
return 0;
}
if(nitems)
*nitems = items_ret;
if(ok)
*ok = true;
return prop_data;
}
bool NETWM::climsg(Window win, long type, long l0, long l1, long l2, long l3, long l4)
{
NETWM::checkInit();
XClientMessageEvent xev;
xev.type = ClientMessage;
xev.window = win;
xev.message_type = type;
xev.format = 32;
xev.data.l[0] = l0;
xev.data.l[1] = l1;
xev.data.l[2] = l2;
xev.data.l[3] = l3;
xev.data.l[4] = l4;
return (XSendEvent(QX11Info::display(), QX11Info::appRootWindow(), False,
(SubstructureNotifyMask | SubstructureRedirectMask),
(XEvent *)&xev) == Success);
}
bool NETWM::climsgwm(Window win, Atom type, Atom arg)
{
NETWM::checkInit();
XClientMessageEvent xev;
xev.type = ClientMessage;
xev.window = win;
xev.message_type = type;
xev.format = 32;
xev.data.l[0] = arg;
xev.data.l[1] = CurrentTime;
return (XSendEvent(QX11Info::display(), win, False, 0L, (XEvent *)&xev) == Success);
}
uint NETWM::netwmDesktopsNumber()
{
NETWM::checkInit();
uint desknum;
quint32 *data;
data = (quint32 *)NETWM::property(QX11Info::appRootWindow(), NETWM::NET_NUMBER_OF_DESKTOPS, XA_CARDINAL, 0);
if(!data)
return 0;
desknum = *data;
XFree(data);
return desknum;
}
uint NETWM::netwmCurrentDesktop()
{
NETWM::checkInit();
uint desk;
quint32 *data;
data = (quint32 *)NETWM::property(QX11Info::appRootWindow(), NETWM::NET_CURRENT_DESKTOP, XA_CARDINAL, 0);
if(!data)
return 0;
desk = *data;
XFree(data);
return desk;
}
qint64 NETWM::netwmPid(Window win)
{
NETWM::checkInit();
qint64 pid = -1;
ulong *data;
data = (ulong *)NETWM::property(win, NETWM::NET_WM_PID, XA_CARDINAL, 0);
if(data)
{
pid = *data;
XFree(data);
}
return pid;
}
bool NETWM::netwmActivateWindow(Window win)
{
NETWM::checkInit();
return NETWM::climsg(win, NETWM::NET_ACTIVE_WINDOW, 2, CurrentTime);
}
QList<Window> NETWM::netwmWindowList()
{
NETWM::checkInit();
QList<Window> list;
int num;
Window *win = reinterpret_cast<Window *>(NETWM::property(QX11Info::appRootWindow(), NETWM::NET_CLIENT_LIST, XA_WINDOW, &num));
if(!win)
{
qDebug("NETWM: Cannot get window list");
return list;
}
for(int i = 0;i < num;i++)
list.append(win[i]);
XFree(win);
return list;
}
int NETWM::netwmDesktop(Window win)
{
NETWM::checkInit();
int desk = 0;
ulong *data;
data = (ulong *)NETWM::property(win, NETWM::NET_WM_DESKTOP, XA_CARDINAL, 0);
if(data)
{
desk = *data;
XFree(data);
}
return desk;
}
NETWM::net_wm_state NETWM::netwmState(Window win)
{
NETWM::checkInit();
net_wm_state nws;
Atom *state;
int num3;
if(!(state = (Atom *)NETWM::property(win, NETWM::NET_WM_STATE, XA_ATOM, &num3)))
return nws;
while(--num3 >= 0)
{
if(state[num3] == NETWM::NET_WM_STATE_MODAL)
{
DBG("NET_WM_STATE_MODAL\n");
nws.modal = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_STICKY)
{
DBG("NET_WM_STATE_STICKY\n");
nws.sticky = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_MAXIMIZED_VERT)
{
DBG("NET_WM_STATE_MAXIMIZED_VERT\n");
nws.maximized_vert = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_MAXIMIZED_HORZ)
{
DBG("NET_WM_STATE_MAXIMIZED_HORZ\n");
nws.maximized_horz = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_SHADED)
{
DBG("NET_WM_STATE_SHADED\n");
nws.shaded = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_SKIP_TASKBAR)
{
DBG("NET_WM_STATE_SKIP_TASKBAR\n");
nws.skip_taskbar = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_SKIP_PAGER)
{
DBG("NET_WM_STATE_SKIP_PAGER\n");
nws.skip_pager = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_HIDDEN)
{
DBG("NET_WM_STATE_HIDDEN\n");
nws.hidden = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_FULLSCREEN)
{
DBG("NET_WM_STATE_FULLSCREEN\n");
nws.fullscreen = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_ABOVE)
{
DBG("NET_WM_STATE_ABOVE\n");
nws.above = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_BELOW)
{
DBG("NET_WM_STATE_BELOW\n");
nws.below = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_STAYS_ON_TOP)
{
DBG("NET_WM_STATE_STAYS_ON_TOP\n");
nws.stays_on_top = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_STAYS_ON_BOTTOM)
{
DBG("NET_WM_STATE_STAYS_ON_BOTTOM\n");
nws.stays_on_bottom = 1;
}
else if(state[num3] == NETWM::NET_WM_STATE_DEMANDS_ATTENTION)
{
DBG("NET_WM_STATE_DEMANDS_ATTENTION\n");
nws.demands_attention = 1;
}
}
nws.valid = true;
XFree(state);
return nws;
}
NETWM::net_wm_window_type NETWM::netwmWindowType(Window win)
{
NETWM::checkInit();
net_wm_window_type nwwt;
Atom *state;
int num3;
bool ok;
if(!(state = (Atom *)NETWM::property(win, NETWM::NET_WM_WINDOW_TYPE, XA_ATOM, &num3, &ok)))
{
if(ok)
{
nwwt.valid = true;
nwwt.normal = 1;
}
return nwwt;
}
nwwt.valid = true;
while(--num3 >= 0)
{
if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DESKTOP)
{
DBG("NET_WM_WINDOW_TYPE_DESKTOP\n");
nwwt.desktop = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DOCK)
{
DBG("NET_WM_WINDOW_TYPE_DOCK\n");
nwwt.dock = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_TOOLBAR)
{
DBG("NET_WM_WINDOW_TYPE_TOOLBAR\n");
nwwt.toolbar = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_MENU)
{
DBG("NET_WM_WINDOW_TYPE_MENU\n");
nwwt.menu = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_UTILITY)
{
DBG("NET_WM_WINDOW_TYPE_UTILITY\n");
nwwt.utility = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_SPLASH)
{
DBG("NET_WM_WINDOW_TYPE_SPLASH\n");
nwwt.splash = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DIALOG)
{
DBG("NET_WM_WINDOW_TYPE_DIALOG\n");
nwwt.dialog = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
{
DBG("NET_WM_WINDOW_TYPE_DROPDOWN_MENU\n");
nwwt.dropdown = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_POPUP_MENU)
{
DBG("NET_WM_WINDOW_TYPE_POPUP_MENU\n");
nwwt.popup = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_TOOLTIP)
{
DBG("NET_WM_WINDOW_TYPE_TOOLTIP\n");
nwwt.tooltip = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_NOTIFICATION)
{
DBG("NET_WM_WINDOW_TYPE_NOTIFICATION\n");
nwwt.notification = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_COMBO)
{
DBG("NET_WM_WINDOW_TYPE_COMBO\n");
nwwt.combo = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_DND)
{
DBG("NET_WM_WINDOW_TYPE_DND\n");
nwwt.dnd = 1;
}
else if(state[num3] == NETWM::NET_WM_WINDOW_TYPE_NORMAL)
{
DBG("NET_WM_WINDOW_TYPE_NORMAL\n");
nwwt.normal = 1;
}
}
XFree(state);
return nwwt;
}
QString NETWM::icccmString(Window win, Atom atom)
{
NETWM::checkInit();
QString s;
char *data;
if(!(data = (char *)NETWM::property(win, atom, XA_STRING)))
return s;
s = QString::fromUtf8(data);
XFree(data);
return s;
}
QString NETWM::icccmUtf8String(Window win, Atom atom)
{
NETWM::checkInit();
Atom type;
int format;
ulong nitems;
ulong bytes_after;
int result;
uchar *tmp = 0;
QString val;
type = None;
result = XGetWindowProperty(QX11Info::display(), win, atom, 0, LONG_MAX, False,
NETWM::UTF8_STRING, &type, &format, &nitems,
&bytes_after, &tmp);
if(result != Success || type == None || !tmp)
return val;
if(type == NETWM::UTF8_STRING && format == 8 && nitems != 0)
val = QString::fromUtf8(reinterpret_cast<char *>(tmp));
XFree(tmp);
return val;
}
QString NETWM::icccmWindowRole(Window win)
{
NETWM::checkInit();
return NETWM::icccmString(win, NETWM::WM_WINDOW_ROLE);
}
QStringList NETWM::icccmClass(Window win)
{
NETWM::checkInit();
QStringList l;
char *data;
if(!(data = (char *)NETWM::property(win, NETWM::WM_CLASS, XA_STRING)))
return l;
l.append(QString::fromUtf8(data));
l.append(QString::fromUtf8(data+strlen(data)+1));
XFree(data);
return l;
}
QString NETWM::icccmName(Window win)
{
NETWM::checkInit();
return NETWM::icccmString(win, NETWM::WM_NAME);
}
QStringList NETWM::icccmCommand(Window win)
{
NETWM::checkInit();
QStringList list;
char **argv;
int argc;
if(!XGetCommand(QX11Info::display(), win, &argv, &argc))
return list;
for(int i = 0;i < argc;i++)
list.append(argv[i]);
XFreeStringList(argv);
return list;
}
#define MO_NETWM_OPAQUE 0xffffffff
void NETWM::transset(Window window, double d)
{
NETWM::checkInit();
Display *dpy = QX11Info::display();
uint opacity = (uint)(d * MO_NETWM_OPAQUE);
if(opacity == MO_NETWM_OPAQUE)
XDeleteProperty(dpy, window, NETWM::NET_WM_WINDOW_OPACITY);
else
XChangeProperty(dpy, window, NETWM::NET_WM_WINDOW_OPACITY,
XA_CARDINAL, 32, PropModeReplace, (uchar *)&opacity, 1L);
XSync(dpy, False);
}
bool NETWM::isComposite()
{
int event_base, error_base;
Display *dpy = QX11Info::display();
// extension is not supported
if(!XCompositeQueryExtension(dpy, &event_base, &error_base))
{
qDebug("NETWM: Composite extension is not supported");
return false;
}
// NETWM-compliant composite manager MUST set selection owner
// of _NET_WM_CM_Sn
Window owner = XGetSelectionOwner(dpy, XInternAtom(dpy, "_NET_WM_CM_S0", False));
return (owner != None);
}
void NETWM::checkInit()
{
if(!NETWM::WM_STATE)
NETWM::init();
}

186
thirdparty/libqnetwm/netwm.h vendored Normal file
View File

@ -0,0 +1,186 @@
/***************************************************************************
* Copyright (C) 2010 by Dmitry 'Krasu' Baryshev *
* ksquirrel.iv@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef NETWM_H
#define NETWM_H
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "fixx11h.h"
#include <QStringList>
#include <QString>
#include <QList>
class NETWM
{
public:
struct net_wm_state
{
net_wm_state();
unsigned int modal : 1;
unsigned int sticky : 1;
unsigned int maximized_vert : 1;
unsigned int maximized_horz : 1;
unsigned int shaded : 1;
unsigned int skip_taskbar : 1;
unsigned int skip_pager : 1;
unsigned int hidden : 1;
unsigned int fullscreen : 1;
unsigned int above : 1;
unsigned int below : 1;
unsigned int stays_on_top : 1;
unsigned int stays_on_bottom : 1;
unsigned int demands_attention : 1;
bool valid;
};
struct net_wm_window_type
{
net_wm_window_type();
unsigned int desktop : 1;
unsigned int dock : 1;
unsigned int toolbar : 1;
unsigned int menu : 1;
unsigned int utility : 1;
unsigned int splash : 1;
unsigned int dialog : 1;
unsigned int dropdown : 1;
unsigned int popup : 1;
unsigned int tooltip : 1;
unsigned int notification : 1;
unsigned int combo : 1;
unsigned int dnd : 1;
unsigned int normal : 1;
bool valid;
};
/*************************************************************************/
static void init();
static void transset(Window, double);
static bool isComposite();
static int setProperty(Window, Atom, long, uchar *, int);
static int setPropertySkipTaskbar(Window);
static int setPropertyOnTop(Window);
static void* property(Window win, Atom prop, Atom type, int *nitems = 0, bool *ok = 0);
static bool climsg(Window win, long type, long l0, long l1 = 0, long l2 = 0, long l3 = 0, long l4 = 0);
static bool climsgwm(Window win, Atom type, Atom arg);
// NETWM helper functions
static qint64 netwmPid(Window win);
static QList<Window> netwmWindowList();
static uint netwmDesktopsNumber();
static uint netwmCurrentDesktop();
static int netwmDesktop(Window win);
static net_wm_state netwmState(Window win);
static net_wm_window_type netwmWindowType(Window win);
static bool netwmActivateWindow(Window win);
// ICCCM helper functions
static QString icccmString(Window win, Atom atom);
static QString icccmUtf8String(Window win, Atom atom);
static QString icccmWindowRole(Window win);
static QStringList icccmClass(Window win);
static QString icccmName(Window win);
static QStringList icccmCommand(Window win);
/*************************************************************************/
/********************************* Atoms *********************************/
/*************************************************************************/
static Atom UTF8_STRING;
static Atom XROOTPMAP_ID;
static Atom WM_STATE;
static Atom WM_CLASS;
static Atom WM_NAME;
static Atom WM_DELETE_WINDOW;
static Atom WM_PROTOCOLS;
static Atom WM_CHANGE_STATE;
static Atom WM_WINDOW_ROLE;
static Atom NET_WORKAREA;
static Atom NET_CLIENT_LIST;
static Atom NET_CLIENT_LIST_STACKING;
static Atom NET_NUMBER_OF_DESKTOPS;
static Atom NET_CURRENT_DESKTOP;
static Atom NET_DESKTOP_NAMES;
static Atom NET_ACTIVE_WINDOW;
static Atom NET_CLOSE_WINDOW;
static Atom NET_SUPPORTED;
static Atom NET_WM_DESKTOP;
static Atom NET_SHOWING_DESKTOP;
static Atom NET_WM_STATE;
static Atom NET_WM_STATE_MODAL;
static Atom NET_WM_STATE_STICKY;
static Atom NET_WM_STATE_MAXIMIZED_VERT;
static Atom NET_WM_STATE_MAXIMIZED_HORZ;
static Atom NET_WM_STATE_SHADED;
static Atom NET_WM_STATE_SKIP_TASKBAR;
static Atom NET_WM_STATE_SKIP_PAGER;
static Atom NET_WM_STATE_HIDDEN;
static Atom NET_WM_STATE_FULLSCREEN;
static Atom NET_WM_STATE_ABOVE;
static Atom NET_WM_STATE_BELOW;
static Atom NET_WM_STATE_STAYS_ON_TOP;
static Atom NET_WM_STATE_STAYS_ON_BOTTOM;
static Atom NET_WM_STATE_DEMANDS_ATTENTION;
static Atom NET_WM_WINDOW_TYPE;
static Atom NET_WM_WINDOW_TYPE_DESKTOP;
static Atom NET_WM_WINDOW_TYPE_DOCK;
static Atom MODERRO_WINDOW_TYPE_DOCK;
static Atom NET_WM_WINDOW_TYPE_TOOLBAR;
static Atom NET_WM_WINDOW_TYPE_MENU;
static Atom NET_WM_WINDOW_TYPE_UTILITY;
static Atom NET_WM_WINDOW_TYPE_SPLASH;
static Atom NET_WM_WINDOW_TYPE_DIALOG;
static Atom NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
static Atom NET_WM_WINDOW_TYPE_POPUP_MENU;
static Atom NET_WM_WINDOW_TYPE_TOOLTIP;
static Atom NET_WM_WINDOW_TYPE_NOTIFICATION;
static Atom NET_WM_WINDOW_TYPE_COMBO;
static Atom NET_WM_WINDOW_TYPE_DND;
static Atom NET_WM_WINDOW_TYPE_NORMAL;
static Atom NET_WM_WINDOW_OPACITY;
static Atom NET_WM_NAME;
static Atom NET_WM_VISIBLE_NAME;
static Atom NET_WM_STRUT;
static Atom NET_WM_STRUT_PARTIAL;
static Atom NET_WM_ICON;
static Atom NET_WM_PID;
private:
static void checkInit();
};
#endif