+ XSendEvent(**otk::display, _window, false, NoEventMask, &ce);
+}
+
+void Client::changeState()
+{
+ unsigned long state[2];
+ state[0] = _wmstate;
+ state[1] = None;
+ otk::Property::set(_window, otk::Property::atoms.wm_state,
+ otk::Property::atoms.wm_state, state, 2);
+
+ Atom netstate[10];
+ int num = 0;
+ if (_modal)
+ netstate[num++] = otk::Property::atoms.net_wm_state_modal;
+ if (_shaded)
+ netstate[num++] = otk::Property::atoms.net_wm_state_shaded;
+ if (_iconic)
+ netstate[num++] = otk::Property::atoms.net_wm_state_hidden;
+ if (_skip_taskbar)
+ netstate[num++] = otk::Property::atoms.net_wm_state_skip_taskbar;
+ if (_skip_pager)
+ netstate[num++] = otk::Property::atoms.net_wm_state_skip_pager;
+ if (_fullscreen)
+ netstate[num++] = otk::Property::atoms.net_wm_state_fullscreen;
+ if (_max_vert)
+ netstate[num++] = otk::Property::atoms.net_wm_state_maximized_vert;
+ if (_max_horz)
+ netstate[num++] = otk::Property::atoms.net_wm_state_maximized_horz;
+ if (_above)
+ netstate[num++] = otk::Property::atoms.net_wm_state_above;
+ if (_below)
+ netstate[num++] = otk::Property::atoms.net_wm_state_below;
+ otk::Property::set(_window, otk::Property::atoms.net_wm_state,
+ otk::Property::atoms.atom, netstate, num);
+
+ calcLayer();
+
+ if (frame)
+ frame->adjustState();
+}
+
+void Client::changeAllowedActions(void)
+{
+ Atom actions[9];
+ int num = 0;
+
+ actions[num++] = otk::Property::atoms.net_wm_action_change_desktop;
+
+ if (_functions & Func_Shade)
+ actions[num++] = otk::Property::atoms.net_wm_action_shade;
+ if (_functions & Func_Close)
+ actions[num++] = otk::Property::atoms.net_wm_action_close;
+ if (_functions & Func_Move)
+ actions[num++] = otk::Property::atoms.net_wm_action_move;
+ if (_functions & Func_Iconify)
+ actions[num++] = otk::Property::atoms.net_wm_action_minimize;
+ if (_functions & Func_Resize)
+ actions[num++] = otk::Property::atoms.net_wm_action_resize;
+ if (_functions & Func_Fullscreen)
+ actions[num++] = otk::Property::atoms.net_wm_action_fullscreen;
+ if (_functions & Func_Maximize) {
+ actions[num++] = otk::Property::atoms.net_wm_action_maximize_horz;
+ actions[num++] = otk::Property::atoms.net_wm_action_maximize_vert;
+ }
+
+ otk::Property::set(_window, otk::Property::atoms.net_wm_allowed_actions,
+ otk::Property::atoms.atom, actions, num);
+
+ // make sure the window isn't breaking any rules now
+
+ if (!(_functions & Func_Shade) && _shaded)
+ if (frame) shade(false);
+ else _shaded = false;
+ if (!(_functions & Func_Iconify) && _iconic)
+ if (frame) setDesktop(openbox->screen(_screen)->desktop());
+ else _iconic = false;
+ if (!(_functions & Func_Fullscreen) && _fullscreen)
+ if (frame) fullscreen(false);
+ else _fullscreen = false;
+ if (!(_functions & Func_Maximize) && (_max_horz || _max_vert))
+ if (frame) maximize(false, 0);
+ else _max_vert = _max_horz = false;
+}
+
+void Client::remaximize()
+{
+ int dir;
+ if (_max_horz && _max_vert)
+ dir = 0;
+ else if (_max_horz)
+ dir = 1;
+ else if (_max_vert)
+ dir = 2;
+ else
+ return; // not maximized
+ _max_horz = _max_vert = false;
+ maximize(true, dir, false);
+}
+
+void Client::applyStartupState()
+{
+ // these are in a carefully crafted order..
+
+ if (_iconic) {
+ _iconic = false;
+ iconify(true);
+ }
+ if (_fullscreen) {
+ _fullscreen = false;
+ fullscreen(true, false);
+ }
+ if (_shaded) {
+ _shaded = false;
+ shade(true);
+ }
+ if (_urgent)
+ fireUrgent();
+
+ if (_max_vert && _max_horz) {
+ _max_vert = _max_horz = false;
+ maximize(true, 0, false);
+ } else if (_max_vert) {
+ _max_vert = false;
+ maximize(true, 2, false);
+ } else if (_max_horz) {
+ _max_horz = false;
+ maximize(true, 1, false);
+ }
+
+ if (_skip_taskbar); // nothing to do for this
+ if (_skip_pager); // nothing to do for this
+ if (_modal); // nothing to do for this
+ if (_above); // nothing to do for this
+ if (_below); // nothing to do for this
+}
+
+void Client::fireUrgent()
+{
+ // call the python UrgentWindow callbacks
+ EventData data(_screen, this, EventAction::UrgentWindow, 0);
+ openbox->bindings()->fireEvent(&data);
+}
+
+void Client::shade(bool shade)
+{
+ if (!(_functions & Func_Shade) || // can't
+ _shaded == shade) return; // already done
+
+ // when we're iconic, don't change the wmstate
+ if (!_iconic)
+ _wmstate = shade ? IconicState : NormalState;
+ _shaded = shade;
+ changeState();
+ frame->adjustSize();