client.cc compiles
This commit is contained in:
parent
22c770d90f
commit
d017db67e4
1 changed files with 292 additions and 0 deletions
292
src/client.cc
Normal file
292
src/client.cc
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
|
|
||||||
|
#include "client.hh"
|
||||||
|
#include "screen.hh"
|
||||||
|
#include "openbox.hh"
|
||||||
|
#include "otk/display.hh"
|
||||||
|
#include "otk/property.hh"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "gettext.h"
|
||||||
|
#define _(str) gettext(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ob {
|
||||||
|
|
||||||
|
OBClient::OBClient(BScreen *screen, Window window)
|
||||||
|
: _screen(screen), _window(window)
|
||||||
|
{
|
||||||
|
assert(_screen);
|
||||||
|
assert(window);
|
||||||
|
|
||||||
|
// initialize vars to false/invalid values
|
||||||
|
_group = 0;
|
||||||
|
_gravity = _base_x = _base_y = _inc_x = _inc_y = _max_x = _max_y = _min_x =
|
||||||
|
_min_y = -1;
|
||||||
|
_state = -1;
|
||||||
|
_type = Type_Normal;
|
||||||
|
_desktop = 0xffffffff - 1;
|
||||||
|
_can_focus = _urgent = _focus_notify = _shaped = _modal = _shaded =
|
||||||
|
_max_horz = _max_vert = _fullscreen = _floating = false;
|
||||||
|
|
||||||
|
|
||||||
|
// update EVERYTHING the first time!!
|
||||||
|
}
|
||||||
|
|
||||||
|
OBClient::~OBClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::updateNormalHints()
|
||||||
|
{
|
||||||
|
XSizeHints size;
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
_gravity = NorthWestGravity;
|
||||||
|
_inc_x = _inc_y = 1;
|
||||||
|
_base_x = _base_y = 0;
|
||||||
|
|
||||||
|
// get the hints from the window
|
||||||
|
if (XGetWMNormalHints(otk::OBDisplay::display, _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 OBClient::updateWMHints()
|
||||||
|
{
|
||||||
|
XWMHints *hints;
|
||||||
|
|
||||||
|
// assume a window takes input if it doesnt specify
|
||||||
|
_can_focus = true;
|
||||||
|
_urgent = false;
|
||||||
|
|
||||||
|
if ((hints = XGetWMHints(otk::OBDisplay::display, _window)) != NULL) {
|
||||||
|
if (hints->flags & InputHint)
|
||||||
|
_can_focus = hints->input;
|
||||||
|
if (hints->flags & XUrgencyHint)
|
||||||
|
_urgent = true;
|
||||||
|
if (hints->flags & WindowGroupHint)
|
||||||
|
if (hints->window_group != _group) {
|
||||||
|
// XXX: remove from the old group if there was one
|
||||||
|
_group = hints->window_group;
|
||||||
|
// XXX: do stuff with the group
|
||||||
|
}
|
||||||
|
XFree(hints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::updateTitle()
|
||||||
|
{
|
||||||
|
const otk::OBProperty *property = Openbox::instance->property();
|
||||||
|
|
||||||
|
_title = "";
|
||||||
|
|
||||||
|
// try netwm
|
||||||
|
if (! property->get(_window, otk::OBProperty::net_wm_name,
|
||||||
|
otk::OBProperty::utf8, &_title)) {
|
||||||
|
// try old x stuff
|
||||||
|
property->get(_window, otk::OBProperty::wm_name,
|
||||||
|
otk::OBProperty::ascii, &_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_title.empty())
|
||||||
|
_title = _("Unnamed Window");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::updateClass()
|
||||||
|
{
|
||||||
|
const otk::OBProperty *property = Openbox::instance->property();
|
||||||
|
|
||||||
|
// set the defaults
|
||||||
|
_app_name = _app_class = "";
|
||||||
|
|
||||||
|
otk::OBProperty::StringVect v;
|
||||||
|
unsigned long num = 2;
|
||||||
|
|
||||||
|
if (! property->get(_window, otk::OBProperty::wm_class,
|
||||||
|
otk::OBProperty::ascii, &num, &v))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (num > 0) _app_name = v[0];
|
||||||
|
if (num > 1) _app_class = v[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::update(const XPropertyEvent &e)
|
||||||
|
{
|
||||||
|
const otk::OBProperty *property = Openbox::instance->property();
|
||||||
|
|
||||||
|
if (e.atom == XA_WM_NORMAL_HINTS)
|
||||||
|
updateNormalHints();
|
||||||
|
else if (e.atom == XA_WM_HINTS)
|
||||||
|
updateWMHints();
|
||||||
|
else if (e.atom == property->atom(otk::OBProperty::net_wm_name) ||
|
||||||
|
e.atom == property->atom(otk::OBProperty::wm_name) ||
|
||||||
|
e.atom == property->atom(otk::OBProperty::net_wm_icon_name) ||
|
||||||
|
e.atom == property->atom(otk::OBProperty::wm_icon_name))
|
||||||
|
updateTitle();
|
||||||
|
else if (e.atom == property->atom(otk::OBProperty::wm_class))
|
||||||
|
updateClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::setWMState(long state)
|
||||||
|
{
|
||||||
|
if (state == _state) return; // no change
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case IconicState:
|
||||||
|
// XXX: cause it to iconify
|
||||||
|
break;
|
||||||
|
case NormalState:
|
||||||
|
// XXX: cause it to uniconify
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::setDesktop(long target)
|
||||||
|
{
|
||||||
|
assert(target >= 0);
|
||||||
|
//assert(target == 0xffffffff || target < MAX);
|
||||||
|
|
||||||
|
// XXX: move the window to the new desktop
|
||||||
|
_desktop = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::setState(StateAction action, long data1, long data2)
|
||||||
|
{
|
||||||
|
const otk::OBProperty *property = Openbox::instance->property();
|
||||||
|
|
||||||
|
if (!(action == State_Add || action == State_Remove ||
|
||||||
|
action == State_Toggle))
|
||||||
|
return; // an invalid action was passed to the client message, ignore it
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i) {
|
||||||
|
Atom state = i == 0 ? data1 : data2;
|
||||||
|
|
||||||
|
if (! state) continue;
|
||||||
|
|
||||||
|
// if toggling, then pick whether we're adding or removing
|
||||||
|
if (action == State_Toggle) {
|
||||||
|
if (state == property->atom(otk::OBProperty::net_wm_state_modal))
|
||||||
|
action = _modal ? State_Remove : State_Add;
|
||||||
|
else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_maximized_vert))
|
||||||
|
action = _max_vert ? State_Remove : State_Add;
|
||||||
|
else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_maximized_horz))
|
||||||
|
action = _max_horz ? State_Remove : State_Add;
|
||||||
|
else if (state == property->atom(otk::OBProperty::net_wm_state_shaded))
|
||||||
|
action = _shaded ? State_Remove : State_Add;
|
||||||
|
else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_fullscreen))
|
||||||
|
action = _fullscreen ? State_Remove : State_Add;
|
||||||
|
else if (state == property->atom(otk::OBProperty::net_wm_state_floating))
|
||||||
|
action = _floating ? State_Remove : State_Add;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == State_Add) {
|
||||||
|
if (state == property->atom(otk::OBProperty::net_wm_state_modal)) {
|
||||||
|
if (_modal) continue;
|
||||||
|
_modal = true;
|
||||||
|
// XXX: give it focus if another window has focus that shouldnt now
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_maximized_vert)){
|
||||||
|
if (_max_vert) continue;
|
||||||
|
_max_vert = true;
|
||||||
|
// XXX: resize the window etc
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_maximized_horz)){
|
||||||
|
if (_max_horz) continue;
|
||||||
|
_max_horz = true;
|
||||||
|
// XXX: resize the window etc
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_shaded)) {
|
||||||
|
if (_shaded) continue;
|
||||||
|
_shaded = true;
|
||||||
|
// XXX: hide the client window
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_fullscreen)) {
|
||||||
|
if (_fullscreen) continue;
|
||||||
|
_fullscreen = true;
|
||||||
|
// XXX: raise the window n shit
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_floating)) {
|
||||||
|
if (_floating) continue;
|
||||||
|
_floating = true;
|
||||||
|
// XXX: raise the window n shit
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // action == State_Remove
|
||||||
|
if (state == property->atom(otk::OBProperty::net_wm_state_modal)) {
|
||||||
|
if (!_modal) continue;
|
||||||
|
_modal = false;
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_maximized_vert)){
|
||||||
|
if (!_max_vert) continue;
|
||||||
|
_max_vert = false;
|
||||||
|
// XXX: resize the window etc
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_maximized_horz)){
|
||||||
|
if (!_max_horz) continue;
|
||||||
|
_max_horz = false;
|
||||||
|
// XXX: resize the window etc
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_shaded)) {
|
||||||
|
if (!_shaded) continue;
|
||||||
|
_shaded = false;
|
||||||
|
// XXX: show the client window
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_fullscreen)) {
|
||||||
|
if (!_fullscreen) continue;
|
||||||
|
_fullscreen = false;
|
||||||
|
// XXX: lower the window to its proper layer
|
||||||
|
} else if (state ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_state_floating)) {
|
||||||
|
if (!_floating) continue;
|
||||||
|
_floating = false;
|
||||||
|
// XXX: lower the window to its proper layer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OBClient::update(const XClientMessageEvent &e)
|
||||||
|
{
|
||||||
|
if (e.format != 32) return;
|
||||||
|
|
||||||
|
const otk::OBProperty *property = Openbox::instance->property();
|
||||||
|
|
||||||
|
if (e.message_type == property->atom(otk::OBProperty::wm_change_state))
|
||||||
|
setWMState(e.data.l[0]);
|
||||||
|
else if (e.message_type ==
|
||||||
|
property->atom(otk::OBProperty::net_wm_desktop))
|
||||||
|
setDesktop(e.data.l[0]);
|
||||||
|
else if (e.message_type == property->atom(otk::OBProperty::net_wm_state))
|
||||||
|
setState((StateAction)e.data.l[0], e.data.l[1], e.data.l[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue