getArea();
getDesktop();
+ // XXX: updateTransientFor();
getType();
// set the decorations and functions
+ _decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
+ Decor_Iconify | Decor_Maximize;
+ _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
switch (_type) {
case Type_Normal:
// normal windows retain all of the possible decorations and
// functionality
- _decorations = Decor_Titlebar | Decor_Handle | Decor_Border |
- Decor_Iconify | Decor_Maximize;
- _functions = Func_Resize | Func_Move | Func_Iconify | Func_Maximize;
case Type_Dialog:
// dialogs cannot be maximized
updateProtocols();
updateNormalHints();
updateWMHints();
- // XXX: updateTransientFor();
updateTitle();
updateIconTitle();
updateClass();
+ updateStrut();
calcLayer();
+ changeState();
}
if (proto[i] == property->atom(otk::OBProperty::wm_delete_window)) {
_decorations |= Decor_Close;
_functions |= Func_Close;
- // XXX: update the decor?
+ if (frame)
+ frame->adjustSize(); // update the decorations
} else if (proto[i] == property->atom(otk::OBProperty::wm_take_focus))
// if this protocol is requested, then the window will be notified
// by the window manager whenever it receives focus
}
+void OBClient::updateStrut()
+{
+ unsigned long num = 4;
+ unsigned long *data;
+ if (!Openbox::instance->property()->get(_window,
+ otk::OBProperty::net_wm_strut,
+ otk::OBProperty::Atom_Cardinal,
+ &num, &data))
+ return;
+
+ if (num == 4) {
+ _strut.left = data[0];
+ _strut.right = data[1];
+ _strut.top = data[2];
+ _strut.bottom = data[3];
+
+ Openbox::instance->screen(_screen)->updateStrut();
+ }
+
+ delete [] data;
+}
+
+
void OBClient::propertyHandler(const XPropertyEvent &e)
{
otk::OtkEventHandler::propertyHandler(e);
else if (e.atom == property->atom(otk::OBProperty::wm_protocols))
updateProtocols();
// XXX: transient for hint
+ else if (e.atom == property->atom(otk::OBProperty::net_wm_strut))
+ updateStrut();
// XXX: strut hint
}
void OBClient::setDesktop(long target)
{
- assert(target >= 0);
+ printf("Setting desktop %ld\n", target);
+ assert(target >= 0 || target == (signed)0xffffffff);
//assert(target == 0xffffffff || target < MAX);
// XXX: move the window to the new desktop (and set root property)
void OBClient::setState(StateAction action, long data1, long data2)
{
const otk::OBProperty *property = Openbox::instance->property();
+ bool restack = false, shadestate = _shaded;
if (!(action == State_Add || action == State_Remove ||
action == State_Toggle))
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_shaded)) {
if (_shaded) continue;
- _shaded = true;
- // XXX: hide the client window
+ // shade when we're all thru here
+ shadestate = true;
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_skip_taskbar)) {
_skip_taskbar = true;
property->atom(otk::OBProperty::net_wm_state_fullscreen)) {
if (_fullscreen) continue;
_fullscreen = true;
- // XXX: raise the window n shit
+ restack = false;
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_above)) {
if (_above) continue;
_above = true;
- // XXX: raise the window n shit
+ restack = true;
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_below)) {
if (_below) continue;
_below = true;
- // XXX: lower the window n shit
+ restack = true;
}
} else { // action == State_Remove
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_shaded)) {
if (!_shaded) continue;
- _shaded = false;
- // XXX: show the client window
+ // unshade when we're all thru here
+ shadestate = false;
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_skip_taskbar)) {
_skip_taskbar = false;
property->atom(otk::OBProperty::net_wm_state_fullscreen)) {
if (!_fullscreen) continue;
_fullscreen = false;
- // XXX: lower the window to its proper layer
+ restack = true;
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_above)) {
if (!_above) continue;
_above = false;
- // XXX: lower the window to its proper layer
+ restack = true;
} else if (state ==
property->atom(otk::OBProperty::net_wm_state_below)) {
if (!_below) continue;
_below = false;
- // XXX: raise the window to its proper layer
+ restack = true;
}
}
}
- calcLayer();
- Openbox::instance->screen(_screen)->restack(true, this); // raise
+ if (shadestate != _shaded)
+ shade(shadestate);
+ if (restack) {
+ calcLayer();
+ Openbox::instance->screen(_screen)->restack(true, this); // raise
+ }
}
} else if (e.message_type ==
property->atom(otk::OBProperty::net_active_window)) {
focus();
+ Openbox::instance->screen(_screen)->restack(true, this); // raise
+ } else {
}
}
-#if defined(SHAPE) || defined(DOXYGEN_IGNORE)
+#if defined(SHAPE)
void OBClient::shapeHandler(const XShapeEvent &e)
{
otk::OtkEventHandler::shapeHandler(e);
_shaped = e.shaped;
+ frame->adjustShape();
}
#endif
-void OBClient::resize(Corner anchor, int w, int h)
+void OBClient::resize(Corner anchor, int w, int h, int x, int y)
{
w -= _base_size.x();
h -= _base_size.y();
w += _base_size.x();
h += _base_size.y();
- int x = _area.x(), y = _area.y();
- switch (anchor) {
- case TopLeft:
- break;
- case TopRight:
- x -= w - _area.width();
- break;
- case BottomLeft:
- y -= h - _area.height();
- break;
- case BottomRight:
- x -= w - _area.width();
- y -= h - _area.height();
- break;
+ if (x == INT_MIN || y == INT_MIN) {
+ x = _area.x();
+ y = _area.y();
+ switch (anchor) {
+ case TopLeft:
+ break;
+ case TopRight:
+ x -= w - _area.width();
+ break;
+ case BottomLeft:
+ y -= h - _area.height();
+ break;
+ case BottomRight:
+ x -= w - _area.width();
+ y -= h - _area.height();
+ break;
+ }
}
_area.setSize(w, h);
+
XResizeWindow(otk::OBDisplay::display, _window, w, h);
// resize the frame to match the request
void OBClient::move(int x, int y)
{
_area.setPos(x, y);
+
// move the frame to be in the requested position
frame->adjustPosition();
}
// XXX: itd be cool to do timeouts and shit here for killing the client's
// process off
+ // like... if the window is around after 5 seconds, then the close button
+ // turns a nice red, and if this function is called again, the client is
+ // explicitly killed.
ce.xclient.type = ClientMessage;
ce.xclient.message_type = property->atom(otk::OBProperty::wm_protocols);
}
+
+void OBClient::setStackLayer(int l)
+{
+ if (l == 0)
+ _above = _below = false; // normal
+ else if (l > 0) {
+ _above = true;
+ _below = false; // above
+ } else {
+ _above = false;
+ _below = true; // below
+ }
+ changeState();
+}
+
+
void OBClient::shade(bool shade)
{
if (shade == _shaded) return; // already done
bool OBClient::focus()
{
- if (!_can_focus || _focused) return false;
+ if (!(_can_focus || _focus_notify) || _focused) return false;
+
+ if (_can_focus)
+ XSetInputFocus(otk::OBDisplay::display, _window, RevertToNone, CurrentTime);
+
+ if (_focus_notify) {
+ XEvent ce;
+ const otk::OBProperty *property = Openbox::instance->property();
+
+ ce.xclient.type = ClientMessage;
+ ce.xclient.message_type = property->atom(otk::OBProperty::wm_protocols);
+ ce.xclient.display = otk::OBDisplay::display;
+ ce.xclient.window = _window;
+ ce.xclient.format = 32;
+ ce.xclient.data.l[0] = property->atom(otk::OBProperty::wm_take_focus);
+ ce.xclient.data.l[1] = Openbox::instance->lastTime();
+ ce.xclient.data.l[2] = 0l;
+ ce.xclient.data.l[3] = 0l;
+ ce.xclient.data.l[4] = 0l;
+ XSendEvent(otk::OBDisplay::display, _window, False, NoEventMask, &ce);
+ }
- XSetInputFocus(otk::OBDisplay::display, _window, RevertToNone, CurrentTime);
return true;
}
corner = TopLeft;
}
- resize(corner, w, h);
- }
-
- if (e.value_mask & (CWX | CWY)) {
+ // if moving AND resizing ...
+ if (e.value_mask & (CWX | CWY)) {
+ int x = (e.value_mask & CWX) ? e.x : _area.x();
+ int y = (e.value_mask & CWY) ? e.y : _area.y();
+ resize(corner, w, h, x, y);
+ } else // if JUST resizing...
+ resize(corner, w, h);
+ } else if (e.value_mask & (CWX | CWY)) { // if JUST moving...
int x = (e.value_mask & CWX) ? e.x : _area.x();
int y = (e.value_mask & CWY) ? e.y : _area.y();
move(x, y);