mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
334 lines
12 KiB
C++
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);
|
||
|
}
|