ede/edewm/Winhints.cpp
2009-02-20 13:05:43 +00:00

334 lines
12 KiB
C++

#include "Frame.h"
#include "Winhints.h"
#include "Desktop.h"
#include "debug.h"
Atom _XA_UTF8_STRING;
Atom _XA_SM_CLIENT_ID;
//ICCCM
Atom _XA_WM_CLIENT_LEADER;
Atom _XA_WM_PROTOCOLS;
Atom _XA_WM_TAKE_FOCUS;
Atom _XA_WM_DELETE_WINDOW;
Atom _XA_WM_STATE;
Atom _XA_WM_CHANGE_STATE;
Atom _XA_WM_COLORMAP_WINDOWS;
//MWM
Atom _XATOM_MWM_HINTS;
Atom _XATOM_MOTIF_WM_INFO;
// Extended WM (NetWM)
Atom _XA_NET_SUPPORTED;
Atom _XA_NET_CLIENT_LIST;
Atom _XA_NET_CLIENT_LIST_STACKING;
Atom _XA_NET_NUM_DESKTOPS;
Atom _XA_NET_DESKTOP_GEOMETRY;
Atom _XA_NET_DESKTOP_VIEWPORT;
Atom _XA_NET_CURRENT_DESKTOP;
Atom _XA_NET_DESKTOP_NAMES;
Atom _XA_NET_ACTIVE_WINDOW;
Atom _XA_NET_WORKAREA;
Atom _XA_NET_SUPPORTING_WM_CHECK;
Atom _XA_NET_VIRTUAL_ROOTS;
Atom _XA_NET_DESKTOP_LAYOUT;
Atom _XA_NET_SHOWING_DESKTOP;
Atom _XA_NET_CLOSE_WINDOW;
Atom _XA_NET_WM_MOVERESIZE;
Atom _XA_NET_RESTACK_WINDOW;
Atom _XA_NET_REQUEST_FRAME_EXTENTS;
Atom _XA_NET_WM_NAME;
Atom _XA_NET_WM_VISIBLE_NAME;
Atom _XA_NET_WM_ICON_NAME;
Atom _XA_NET_WM_ICON_VISIBLE_NAME;
Atom _XA_NET_WM_DESKTOP;
Atom _XA_NET_WM_WINDOW_TYPE;
Atom _XA_NET_WM_WINDOW_TYPE_DESKTOP;
Atom _XA_NET_WM_WINDOW_TYPE_DOCK;
Atom _XA_NET_WM_WINDOW_TYPE_TOOLBAR;
Atom _XA_NET_WM_WINDOW_TYPE_MENU;
Atom _XA_NET_WM_WINDOW_TYPE_UTIL;
Atom _XA_NET_WM_WINDOW_TYPE_SPLASH;
Atom _XA_NET_WM_WINDOW_TYPE_DIALOG;
Atom _XA_NET_WM_WINDOW_TYPE_NORMAL;
Atom _XA_NET_WM_STATE;
Atom _XA_NET_WM_STATE_MODAL;
Atom _XA_NET_WM_STATE_STICKY;
Atom _XA_NET_WM_STATE_MAXIMIZED_VERT;
Atom _XA_NET_WM_STATE_MAXIMIZED_HORZ;
Atom _XA_NET_WM_STATE_SHADED;
Atom _XA_NET_WM_STATE_SKIP_TASKBAR;
Atom _XA_NET_WM_STATE_SKIP_PAGER;
Atom _XA_NET_WM_STATE_HIDDEN; // new in spec. 1.3
Atom _XA_NET_WM_STATE_FULLSCREEN; // new in spec. 1.3
Atom _XA_NET_WM_STATE_ABOVE; // new in spec. 1.3
Atom _XA_NET_WM_STATE_BELOW; // new in spec. 1.3
Atom _XA_NET_WM_STATE_DEMANDS_ATTENTION; // new in spec. 1.3
Atom _XA_NET_WM_ALLOWED_ACTIONS;
Atom _XA_NET_WM_ACTION_MOVE;
Atom _XA_NET_WM_ACTION_RESIZE;
Atom _XA_NET_WM_ACTION_MINIMIZE;
Atom _XA_NET_WM_ACTION_SHADE;
Atom _XA_NET_WM_ACTION_STICK;
Atom _XA_NET_WM_ACTION_MAXIMIZE_HORZ;
Atom _XA_NET_WM_ACTION_MAXIMIZE_VERT;
Atom _XA_NET_WM_ACTION_FULLSCREEN;
Atom _XA_NET_WM_ACTION_CHANGE_DESKTOP;
Atom _XA_NET_WM_ACTION_CLOSE;
Atom _XA_NET_WM_STRUT;
Atom _XA_NET_WM_STRUT_PARTIAL;
Atom _XA_NET_WM_ICON_GEOMETRY;
Atom _XA_NET_WM_ICON;
Atom _XA_NET_WM_PID;
Atom _XA_NET_WM_HANDLED_ICONS;
Atom _XA_NET_WM_USER_TIME;
Atom _XA_NET_FRAME_EXTENTS;
Atom _XA_NET_WM_PING;
Atom _XA_NET_WM_SYNC_REQUEST;
Atom _XA_NET_WM_STATE_STAYS_ON_TOP;
//KDE1
Atom _XA_KWM_WIN_ICON;
//EDE
Atom _XA_EDE_WM_ACTION;
Atom _XA_EDE_WM_LOGOUT;
Atom _XA_EDE_WM_RESTORE_SIZE;
#define CNT(x) (sizeof(x)/sizeof(x[0]))
static bool atoms_inited = false;
void init_atoms()
{
if(atoms_inited) return;
struct {
Atom *atom;
const char *name;
} atom_info[] = {
{ &_XA_UTF8_STRING, "UTF8_STRING" },
{ &_XA_SM_CLIENT_ID, "SM_CLIENT_ID" },
//ICCCM
{ &_XA_WM_PROTOCOLS, "WM_PROTOCOLS" },
{ &_XA_WM_TAKE_FOCUS, "WM_TAKE_FOCUS" },
{ &_XA_WM_DELETE_WINDOW, "WM_DELETE_WINDOW" },
{ &_XA_WM_STATE, "WM_STATE" },
{ &_XA_WM_CHANGE_STATE, "WM_CHANGE_STATE" },
{ &_XA_WM_COLORMAP_WINDOWS, "WM_COLORMAP_WINDOWS" },
{ &_XA_WM_CLIENT_LEADER, "WM_CLIENT_LEADER" },
//MWM
{ &_XATOM_MWM_HINTS, _XA_MOTIF_WM_HINTS },
{ &_XATOM_MOTIF_WM_INFO, _XA_MOTIF_WM_INFO },
//KDE1
{ &_XA_KWM_WIN_ICON, "KWM_WIN_ICON" },
//Extended WM
{ &_XA_NET_SUPPORTED, "_NET_SUPPORTED" },
{ &_XA_NET_CLIENT_LIST, "_NET_CLIENT_LIST" },
{ &_XA_NET_CLIENT_LIST_STACKING, "_NET_CLIENT_LIST_STACKING" },
{ &_XA_NET_NUM_DESKTOPS, "_NET_NUMBER_OF_DESKTOPS" },
{ &_XA_NET_DESKTOP_GEOMETRY,"_NET_DESKTOP_GEOMETRY" },
{ &_XA_NET_DESKTOP_VIEWPORT,"_NET_DESKTOP_VIEWPORT" },
{ &_XA_NET_CURRENT_DESKTOP, "_NET_CURRENT_DESKTOP" },
{ &_XA_NET_DESKTOP_NAMES, "_NET_DESKTOP_NAMES" },
{ &_XA_NET_ACTIVE_WINDOW, "_NET_ACTIVE_WINDOW" },
{ &_XA_NET_WORKAREA, "_NET_WORKAREA" },
{ &_XA_NET_SUPPORTING_WM_CHECK, "_NET_SUPPORTING_WM_CHECK" },
{ &_XA_NET_VIRTUAL_ROOTS, "_NET_VIRTUAL_ROOTS" },
{ &_XA_NET_DESKTOP_LAYOUT, "_NET_DESKTOP_LAYOUT" },
{ &_XA_NET_SHOWING_DESKTOP, "_NET_SHOWING_DESKTOP" },
{ &_XA_NET_CLOSE_WINDOW, "_NET_CLOSE_WINDOW" },
{ &_XA_NET_WM_MOVERESIZE, "_NET_WM_MOVERESIZE" },
{ &_XA_NET_RESTACK_WINDOW, "_NET_RESTACK_WINDOW" },
{ &_XA_NET_REQUEST_FRAME_EXTENTS, "_NET_REQUEST_FRAME_EXTENTS" },
{ &_XA_NET_WM_NAME, "_NET_WM_NAME" },
{ &_XA_NET_WM_VISIBLE_NAME, "_NET_WM_VISIBLE_NAME" },
{ &_XA_NET_WM_ICON_NAME, "_NET_WM_ICON_NAME" },
{ &_XA_NET_WM_ICON_VISIBLE_NAME, "_NET_WM_ICON_VISIBLE_NAME" },
{ &_XA_NET_WM_DESKTOP, "_NET_WM_DESKTOP" },
{ &_XA_NET_WM_WINDOW_TYPE, "_NET_WM_WINDOW_TYPE" },
{ &_XA_NET_WM_WINDOW_TYPE_DESKTOP, "_NET_WM_WINDOW_TYPE_DESKTOP" },
{ &_XA_NET_WM_WINDOW_TYPE_DOCK, "_NET_WM_WINDOW_TYPE_DOCK" },
{ &_XA_NET_WM_WINDOW_TYPE_TOOLBAR, "_NET_WM_WINDOW_TYPE_TOOLBAR" },
{ &_XA_NET_WM_WINDOW_TYPE_MENU, "_NET_WM_WINDOW_TYPE_MENU" },
{ &_XA_NET_WM_WINDOW_TYPE_UTIL, "_NET_WM_WINDOW_TYPE_UTILITY" },
{ &_XA_NET_WM_WINDOW_TYPE_SPLASH, "_NET_WM_WINDOW_TYPE_SPLASH" },
{ &_XA_NET_WM_WINDOW_TYPE_DIALOG, "_NET_WM_WINDOW_TYPE_DIALOG" },
{ &_XA_NET_WM_WINDOW_TYPE_NORMAL, "_NET_WM_WINDOW_TYPE_NORMAL" },
{ &_XA_NET_WM_STATE, "_NET_WM_STATE" },
{ &_XA_NET_WM_STATE_MODAL, "_NET_WM_STATE_MODAL" },
{ &_XA_NET_WM_STATE_STICKY, "_NET_WM_STATE_STICKY" },
{ &_XA_NET_WM_STATE_MAXIMIZED_VERT, "_NET_WM_STATE_MAXIMIZED_VERT" },
{ &_XA_NET_WM_STATE_MAXIMIZED_HORZ, "_NET_WM_STATE_MAXIMIZED_HORZ" },
{ &_XA_NET_WM_STATE_SHADED, "_NET_WM_STATE_SHADED" },
{ &_XA_NET_WM_STATE_SKIP_TASKBAR, "_NET_WM_STATE_SKIP_TASKBAR" },
{ &_XA_NET_WM_STATE_SKIP_PAGER, "_NET_WM_STATE_SKIP_PAGER" },
{ &_XA_NET_WM_STATE_HIDDEN, "_NET_WM_STATE_HIDDEN" },
{ &_XA_NET_WM_STATE_FULLSCREEN, "_NET_WM_STATE_FULLSCREEN" },
{ &_XA_NET_WM_STATE_ABOVE, "_NET_WM_STATE_ABOVE" },
{ &_XA_NET_WM_STATE_BELOW, "_NET_WM_STATE_BELOW" },
{ &_XA_NET_WM_STATE_DEMANDS_ATTENTION, "_NET_WM_STATE_DEMANDS_ATTENTION" },
{ &_XA_NET_WM_ALLOWED_ACTIONS, "_NET_WM_ALLOWED_ACTIONS" },
{ &_XA_NET_WM_ACTION_MOVE, "_NET_WM_ACTION_MOVE" },
{ &_XA_NET_WM_ACTION_RESIZE, "_NET_WM_ACTION_RESIZE" },
{ &_XA_NET_WM_ACTION_MINIMIZE, "_NET_WM_ACTION_MINIMIZE" },
{ &_XA_NET_WM_ACTION_SHADE, "_NET_WM_ACTION_SHADE" },
{ &_XA_NET_WM_ACTION_STICK, "_NET_WM_ACTION_STICK" },
{ &_XA_NET_WM_ACTION_MAXIMIZE_HORZ, "_NET_WM_ACTION_MAXIMIZE_HORZ" },
{ &_XA_NET_WM_ACTION_MAXIMIZE_VERT, "_NET_WM_ACTION_MAXIMIZE_VERT" },
{ &_XA_NET_WM_ACTION_FULLSCREEN, "_NET_WM_ACTION_FULLSCREEN" },
{ &_XA_NET_WM_ACTION_CHANGE_DESKTOP, "_NET_WM_ACTION_CHANGE_DESKTOP" },
{ &_XA_NET_WM_ACTION_CLOSE, "_NET_WM_ACTION_CLOSE" },
{ &_XA_NET_WM_STRUT, "_NET_WM_STRUT" },
{ &_XA_NET_WM_STRUT_PARTIAL, "_NET_WM_STRUT_PARTIAL" },
{ &_XA_NET_WM_ICON_GEOMETRY, "_NET_WM_ICON_GEOMETRY" },
{ &_XA_NET_WM_ICON, "_NET_WM_ICON" },
{ &_XA_NET_WM_PID, "_NET_WM_PID" },
{ &_XA_NET_WM_HANDLED_ICONS, "_NET_WM_HANDLED_ICONS" },
{ &_XA_NET_WM_USER_TIME, "_NET_WM_USER_TIME" },
{ &_XA_NET_FRAME_EXTENTS, "_NET_FRAME_EXTENTS" },
{ &_XA_NET_WM_PING, "_NET_WM_PING" },
{ &_XA_NET_WM_SYNC_REQUEST, "_NET_WM_SYNC_REQUEST" },
/* the next one is not in the spec but KDE use it */
{ &_XA_NET_WM_STATE_STAYS_ON_TOP, "_NET_WM_STATE_STAYS_ON_TOP" },
/* KDE 1 */
{ &_XA_KWM_WIN_ICON, "_NET_KWM_WIN_ICON" },
/* EDE specific message */
{ &_XA_EDE_WM_ACTION, "_EDE_WM_ACTION" },
{ &_XA_EDE_WM_LOGOUT, "_EDE_WM_LOGOUT" },
{ &_XA_EDE_WM_RESTORE_SIZE, "_EDE_WM_RESTORE_SIZE" }
/*
{ &_XA_CLIPBOARD, "CLIPBOARD" },
{ &_XA_TARGETS, "TARGETS" },
{ &XA_XdndAware, "XdndAware" },
{ &XA_XdndEnter, "XdndEnter" },
{ &XA_XdndLeave, "XdndLeave" },
{ &XA_XdndPosition, "XdndPosition" },
{ &XA_XdndStatus, "XdndStatus" },
{ &XA_XdndDrop, "XdndDrop" },
{ &XA_XdndFinished, "XdndFinished" }
*/
};
unsigned int i;
for(i = 0; i < CNT(atom_info); i++) {
*(atom_info[i].atom) = XInternAtom(fl_display, atom_info[i].name, False);
}
atoms_inited = true;
}
void register_protocols(Window root)
{
static bool protos_registered = false;
if(protos_registered) return;
Atom net_proto[] = {
_XA_NET_SUPPORTED,
_XA_NET_CLIENT_LIST,
_XA_NET_CLIENT_LIST_STACKING,
_XA_NET_NUM_DESKTOPS,
_XA_NET_DESKTOP_GEOMETRY,
_XA_NET_DESKTOP_VIEWPORT,
_XA_NET_SHOWING_DESKTOP,
_XA_NET_CURRENT_DESKTOP,
_XA_NET_DESKTOP_NAMES,
_XA_NET_ACTIVE_WINDOW,
_XA_NET_WORKAREA,
_XA_NET_SUPPORTING_WM_CHECK,
//_XA_NET_VIRTUAL_ROOTS, //hmmm.... I didnt understand this one...
_XA_NET_CLOSE_WINDOW,
//_XA_NET_WM_MOVERESIZE,
_XA_NET_WM_NAME,
//_XA_NET_WM_VISIBLE_NAME,
_XA_NET_WM_ICON_NAME,
//_XA_NET_WM_ICON_VISIBLE_NAME,
_XA_NET_WM_DESKTOP,
_XA_NET_WM_WINDOW_TYPE,
_XA_NET_WM_WINDOW_TYPE_DESKTOP,
_XA_NET_WM_WINDOW_TYPE_DOCK,
_XA_NET_WM_WINDOW_TYPE_TOOLBAR,
_XA_NET_WM_WINDOW_TYPE_MENU,
_XA_NET_WM_WINDOW_TYPE_UTIL,
_XA_NET_WM_WINDOW_TYPE_SPLASH,
_XA_NET_WM_WINDOW_TYPE_DIALOG,
_XA_NET_WM_WINDOW_TYPE_NORMAL,
//_XA_NET_WM_STATE,
//_XA_NET_WM_STATE_MODAL,
//_XA_NET_WM_STATE_STICKY,
//_XA_NET_WM_STATE_MAXIMIZED_VERT,
//_XA_NET_WM_STATE_MAXIMIZED_HORZ,
//_XA_NET_WM_STATE_SHADED,
//_XA_NET_WM_STATE_SKIP_TASKBAR,
//_XA_NET_WM_STATE_SKIP_PAGER,
// the next one is not in the spec but KDE use it
//_XA_NET_WM_STATE_STAYS_ON_TOP,
_XA_NET_WM_STRUT
//_XA_NET_WM_ICON_GEOMETRY,
//_XA_NET_WM_ICON,
//_XA_NET_WM_PID,
//_XA_NET_WM_HANDLED_ICONS,
//_XA_NET_WM_PING
};
//Set supported NET protos
XChangeProperty(fl_display, root,
_XA_NET_SUPPORTED, XA_ATOM, 32, PropModeReplace,
(unsigned char *)net_proto, CNT(net_proto));
Window support_xid = XCreateSimpleWindow(fl_display, root, -200, -200, 5, 5, 0, 0, 0);
//NET:
XChangeProperty(fl_display, support_xid,
_XA_NET_SUPPORTING_WM_CHECK, XA_WINDOW, 32,
PropModeReplace, (unsigned char *)&support_xid, 1);
XChangeProperty(fl_display, root,
_XA_NET_SUPPORTING_WM_CHECK, XA_WINDOW, 32,
PropModeReplace, (unsigned char *)&support_xid, 1);
protos_registered = true;
}
void Frame::get_protocols()
{
unsigned long n;
Atom* p = (Atom*)getProperty(_XA_WM_PROTOCOLS, XA_ATOM, &n);
if(p) {
DBG("get_protocols()");
clear_flag(DELETE_WIN_PRT|TAKE_FOCUS_PRT);
for(unsigned int i = 0; i < n; ++i) {
if(p[i]==_XA_WM_DELETE_WINDOW) {
set_frame_flag(DELETE_WIN_PRT);
} else if(p[i]==_XA_WM_TAKE_FOCUS) {
set_frame_flag(TAKE_FOCUS_PRT);
}
}
}
XFree((char*)p);
}
void Frame::get_wm_hints()
{
if(wm_hints) {
XFree((char *)wm_hints);
wm_hints = 0;
}
wm_hints = XGetWMHints(fl_display, window_);
}
void Frame::update_wm_hints()
{
if(!wm_hints) return;
if((wm_hints->flags & InputHint) && !wm_hints->input)
set_frame_flag(NO_FOCUS);
}