-// -*- mode: C++; indent-tabs-mode: nil; -*-
-// window.cc for Epistophy - a key handler for NETWM/EWMH window managers.
+// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
+// window.cc for Epistrophy - a key handler for NETWM/EWMH window managers.
// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
//
// Permission is hereby granted, free of charge, to any person obtaining a
#include "epist.hh"
#include "screen.hh"
#include "window.hh"
-#include "../../src/XAtom.hh"
+#include "../../src/xatom.hh"
+
+ // defined by black/openbox
+const unsigned long XWindow::PropBlackboxAttributesElements;
+const unsigned long XWindow::AttribDecoration;
+const unsigned long XWindow::DecorNone;
+const unsigned long XWindow::DecorNormal;
+
XWindow::XWindow(epist *epist, screen *screen, Window window)
: _epist(epist), _screen(screen), _xatom(epist->xatom()), _window(window) {
XSelectInput(_epist->getXDisplay(), _window,
PropertyChangeMask | StructureNotifyMask);
+ updateBlackboxAttributes();
+ updateNormalHints();
+ updateWMHints();
updateDimentions();
- updateGravity();
updateState();
updateDesktop();
updateTitle();
}
-void XWindow::updateGravity() {
+void XWindow::updateBlackboxAttributes() {
+ unsigned long *data;
+ unsigned long num = PropBlackboxAttributesElements;
+
+ _decorated = true;
+
+ if (_xatom->getValue(_window,
+ XAtom::blackbox_attributes, XAtom::blackbox_attributes,
+ num, &data)) {
+ if (num == PropBlackboxAttributesElements)
+ if (data[0] & AttribDecoration)
+ _decorated = (data[4] != DecorNone);
+ delete data;
+ }
+}
+
+
+void XWindow::updateNormalHints() {
XSizeHints size;
long ret;
- if (XGetWMNormalHints(_epist->getXDisplay(), _window, &size, &ret) &&
- (size.flags & PWinGravity))
- _gravity = size.win_gravity;
- else
- _gravity = NorthWestGravity;
+ // defaults
+ _gravity = NorthWestGravity;
+ _inc_x = _inc_y = 1;
+ _base_x = _base_y = 0;
+
+ if (XGetWMNormalHints(_epist->getXDisplay(), _window, &size, &ret)) {
+ if (size.flags & PWinGravity)
+ _gravity = size.win_gravity;
+ if (size.flags & PBaseSize) {
+ _base_x = size.base_width;
+ _base_y = size.base_height;
+ }
+ if (size.flags & PResizeInc) {
+ _inc_x = size.width_inc;
+ _inc_y = size.height_inc;
+ }
+ }
+}
+
+
+void XWindow::updateWMHints() {
+ XWMHints *hints;
+
+ // assume a window takes input if it doesnt specify
+ _can_focus = True;
+
+ if ((hints = XGetWMHints(_epist->getXDisplay(), _window)) != NULL) {
+ if (hints->flags & InputHint)
+ _can_focus = hints->input;
+ XFree(hints);
+ }
}
break;
case PropertyNotify:
if (e.xproperty.atom == XA_WM_NORMAL_HINTS)
- updateGravity();
+ updateNormalHints();
+ else if (e.xproperty.atom == XA_WM_HINTS)
+ updateWMHints();
+ else if (e.xproperty.atom == _xatom->getAtom(XAtom::blackbox_attributes))
+ updateBlackboxAttributes();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_state))
updateState();
else if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_desktop))
}
-void XWindow::focus() const {
- // this will also unshade the window..
- _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_active_window,
- _window);
+void XWindow::focus(bool raise) const {
+ // this will cause the window to be uniconified also
+
+ if (raise) {
+ _xatom->sendClientMessage(_screen->rootWindow(), XAtom::net_active_window,
+ _window);
+ } else {
+ XSetInputFocus(_epist->getXDisplay(), _window, None, CurrentTime);
+ }
}
}
-void XWindow::resize(unsigned int width, unsigned int height) const {
- XResizeWindow(_epist->getXDisplay(), _window, width, height);
+void XWindow::resizeRel(int dwidth, int dheight) const {
+ // resize in increments if requested by the window
+ unsigned int width = _rect.width(), height = _rect.height();
+
+ unsigned int wdest = width + (dwidth * _inc_x) / _inc_x * _inc_x + _base_x;
+ unsigned int hdest = height + (dheight * _inc_y) / _inc_y * _inc_y + _base_y;
+
+ XResizeWindow(_epist->getXDisplay(), _window, wdest, hdest);
+}
+
+
+void XWindow::resizeAbs(unsigned int width, unsigned int height) const {
+ // resize in increments if requested by the window
+
+ unsigned int wdest = width / _inc_x * _inc_x + _base_x;
+ unsigned int hdest = height / _inc_y * _inc_y + _base_y;
+
+ if (width > wdest) {
+ while (width > wdest)
+ wdest += _inc_x;
+ } else {
+ while (width < wdest)
+ wdest -= _inc_x;
+ }
+ if (height > hdest) {
+ while (height > hdest)
+ hdest += _inc_y;
+ } else {
+ while (height < hdest)
+ hdest -= _inc_y;
+ }
+
+ XResizeWindow(_epist->getXDisplay(), _window, wdest, hdest);
}
break;
}
}
+
+
+void XWindow::decorate(bool d) const {
+ _xatom->sendClientMessage(_screen->rootWindow(),
+ XAtom::blackbox_change_attributes,
+ _window, AttribDecoration,
+ 0, 0, 0, (d ? DecorNormal : DecorNone));
+}