/* Action.cc
Copyright © 2003 David Reveman.
This file is part of Waimea.
Waimea is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Waimea is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with Waimea; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
#include <X11/Xlib.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#endif // STDC_HEADERS
#ifdef LIMITS_H
# include <limits.h>
#endif // LIMITS_H
#ifdef HAVE_UNISTD_H
# include <unistd.h>
# include <sys/types.h>
# include <sys/wait.h>
#endif // HAVE_UNISTD_H
}
#include "Action.hh"
#include "Waimea.hh"
Tst<ActionFunc> *actionfunction_tst;
Tst<long int> *client_window_state_tst;
Tst<int> *event_tst;
Tst<int> *window_type_tst;
WindowObject::WindowObject(WaScreen *_ws, Window win_id, int win_type) :
RefCounted<WindowObject>(this) {
id = win_id;
type = win_type;
ws = _ws;
stacking = NoStackingType;
}
WindowObject::~WindowObject(void) {
if (stacking != NoStackingType && ws) {
switch (stacking) {
case NormalStackingType:
ws->stacking_list.remove(id);
break;
case AlwaysOnTopStackingType:
ws->aot_stacking_list.remove(id);
break;
case AlwaysAtBottomStackingType:
ws->aab_stacking_list.remove(id);
break;
default:
break;
}
}
}
void WindowObject::setStacking(StackingType _stacking) {
if (! ws || (stacking == _stacking)) return;
switch (stacking) {
case NormalStackingType:
ws->stacking_list.remove(id);
break;
case AlwaysOnTopStackingType:
ws->aot_stacking_list.remove(id);
break;
case AlwaysAtBottomStackingType:
ws->aab_stacking_list.remove(id);
break;
default:
break;
}
switch (_stacking) {
case NormalStackingType:
if (stacking == AlwaysOnTopStackingType)
ws->stacking_list.push_front(id);
else
ws->stacking_list.push_back(id);
break;
case AlwaysOnTopStackingType:
ws->aot_stacking_list.push_back(id);
break;
case AlwaysAtBottomStackingType:
ws->aab_stacking_list.push_front(id);
break;
default:
break;
}
stacking = _stacking;
}
ActionList::ActionList(WaScreen *_ws, char *_name) :
RefCounted<ActionList>(this) {
ws = _ws;
name = WA_STRDUP(_name);
}
ActionList::~ActionList(void) {
clear();
if (name) delete [] name;
}
void ActionList::inheritContent(ActionList *inherit) {
list<Action *>::iterator iit = inherit->actionlist.begin();
for (; iit != inherit->actionlist.end(); iit++) {
list<Action *>::iterator it = actionlist.begin();
for (; it != actionlist.end() &&
(*it)->priority <= (*iit)->priority; it++);
actionlist.insert(it, (*iit)->ref());
}
}
void ActionList::clear(void) {
while (! actionlist.empty()) {
actionlist.back()->unref();
actionlist.pop_back();
}
}
Action::Action(void) : RefCounted<Action>(this) {
func = NULL;
param = NULL;
type = detail = x11mod = x11nmod = wamod = wanmod = 0;
replay = false;
delay = 0;
timer_id = 0;
periodic_timer = false;
priority = 0;
ws = NULL;
memset(&pointer.any, 0, sizeof(pointer));
}
Action::~Action(void) {
if (param) delete [] param;
}
bool Action::match(EventDetail *ed) {
if (ed->type == type) {
if (((!detail) || (!ed->detail)) || (detail == ed->detail)) {
if ((x11mod & ed->x11mod) != x11mod) return false;
if ((wamod & ed->wamod) != wamod) return false;
if (x11nmod & ed->x11mod) return false;
if (wanmod & ed->wamod) return false;
return true;
}
}
return false;
}
static const struct EventMap {
char *name;
int event;
} event_map[] = {
{ "keypress", KeyPress },
{ "keyrelease", KeyRelease },
{ "buttonpress", ButtonPress },
{ "buttonrelease", ButtonRelease },
{ "enternotify", EnterNotify },
{ "leavenotify", LeaveNotify },
{ "maprequest", MapRequest },
{ "focusin", FocusIn },
{ "focusout", FocusOut },
{ "doubleclick", DoubleClick },
{ "windowstatechangenotify", WindowStateChangeNotify },
{ "stateaddnotify", StateAddNotify },
{ "stateremovenotify", StateRemoveNotify },
{ "viewportchangenotify", ViewportChangeNotify },
{ "desktopchangenotify", DesktopChangeNotify },
{ "restartnotify", RestartNotify },
{ "exitnotify", ExitNotify },
{ "createwindownotify", CreateWindowNotify },
{ "destroywindownotify", DestroyWindowNotify },
{ "raisenotify", RaiseNotify },
{ "lowernotify", LowerNotify },
{ "activewindowchangenotify", ActiveWindowChangeNotify },
{ "menumapnotify", MenuMapNotify },
{ "menuunmapnotify", MenuUnmapNotify },
{ "submenumapnotify", SubmenuMapNotify },
{ "submenuunmapnotify", SubmenuUnmapNotify },
{ "dockappaddrequest", DockappAddRequest }
};
void Action::applyAttributes(Parser *parser, Tst<char *> *attr) {
char *value = parser->attrGetString(attr, "function", NULL);
if (value) {
Tst<ActionFunc>::iterator it = actionfunction_tst->find(value);
if (it != actionfunction_tst->end()) func = *it;
if (! func)
parser->warning("unknown action function: %s\n", value);
} else
parser->warning("required attribute=function is missing\n");
value = parser->attrGetString(attr, "parameter", NULL);
if (value) {
if (param) delete [] param;
if (func == &AWindowObject::setCursor) {
#ifdef XCURSOR
char *cursorfile = smartfile(value, parser->filename, false);
if (cursorfile) {
pointer.cursor = ws->waimea->cursor->getCursor(cursorfile);
delete [] cursorfile;
} else
#endif // XCURSOR
pointer.cursor = ws->waimea->cursor->getCursor(value);
} else
param = WA_STRDUP(value);
}
value = parser->attrGetString(attr, "event", NULL);
if (value) {
Tst<int>::iterator it = event_tst->find(value);
if (it != event_tst->end()) type = *it;
else
parser->warning("unknown event type: %s\n", value);
} else
parser->warning("required attribute=event is missing\n");
bool detail_set = false;
value = parser->attrGetString(attr, "detail", NULL);
if (type == ButtonPress || type == ButtonRelease) {
value = parser->attrGetString(attr, "button", value);
if (value) {
if (! strncasecmp(value, "anybutton", 9)) {
detail = AnyButton;
detail_set = true;
}
else if (! strncasecmp(value, "button", 6)) {
if (value[6] != '\0') {
int button = atoi(&value[6]);
if (button > 0 && button < 100) {
detail = button;
detail_set = true;
}
}
}
}
} else if (type == KeyPress || type == KeyRelease) {
value = parser->attrGetString(attr, "key", value);
int keycode = 0;
if (value) {
if (! strncmp(value, "0x", 2))
keycode = strtol(value, NULL, 16);
else {
KeySym keysym = XStringToKeysym(value);
if (keysym == NoSymbol) {
parser->warning("unknown keysymbol: %s\n", value);
detail = 0;
detail_set = true;
} else {
keycode = XKeysymToKeycode(parser->ws->display, keysym);
}
}
} else {
value = parser->attrGetString(attr, "keycode", value);
if (value) {
keycode = strtol(value, NULL, 16);
}
}
if (keycode) {
detail_set = true;
if (keycode < parser->ws->waimea->min_key ||
keycode > parser->ws->waimea->max_key) {
parser->warning("bad keycode: 0x%x\n", keycode);
detail = 0;
} else
detail = keycode;
}
}
if (value) {
if (! detail_set)
detail = (unsigned int) atoi(value);
}
priority = parser->attrGetInt(attr, "priority", 0);
delay = parser->attrGetUint(attr, "delay", 0);
timer_id = parser->attrGetUint(attr, "timer_id", 0);
periodic_timer = parser->attrGetBool(attr, "periodic_timer", false);
replay = parser->attrGetBool(attr, "pass_through", false);
}
AWindowObject::AWindowObject(WaScreen *_ws, Window _id, int _type,
WaStringMap *sm, char *_window_name) :
WindowObject(_ws, _id, _type) {
if (_window_name)
window_name = WA_STRDUP(_window_name);
else
window_name = NULL;
window_state_mask = 0;
memset(actionlists, 0, sizeof(actionlists));
memset(default_actionlists, 0, sizeof(default_actionlists));
ids = NULL;
resetActionList(sm);
}
AWindowObject::~AWindowObject(void) {
if (ids) ids->unref();
if (window_name) delete [] window_name;
for (int i = 0; i < WIN_STATE_LAST; i++) {
if (actionlists[i]) actionlists[i]->unref();
if (default_actionlists[i]) default_actionlists[i]->unref();
}
}
void AWindowObject::resetActionList(WaStringMap *sm) {
if (ids) ids->unref();
ids = NULL;
if (sm) ids = sm;
resetActionList();
}
void AWindowObject::resetActionList(void) {
list<ActionRegex *> *ls = NULL;
if (! ws) return;
switch ((type == SubwindowType)?
((DWindowObject *) this)->decor_root->type:
type) {
case WindowType:
case WindowFrameType:
ls = &ws->window_actionlists;
break;
case DockHandlerType:
ls = &ws->dockappholder_actionlists;
break;
case DockAppType:
ls = &ws->dockapp_actionlists;
break;
case MenuItemType:
ls = &ws->menu_actionlists;
break;
case RootType:
ls = &ws->root_actionlists;
break;
case EdgeType:
ls = &ws->screenedge_actionlists;
break;
}
for (int i = 0; i < WIN_STATE_LAST; i++) {
if (actionlists[i]) actionlists[i]->unref();
actionlists[i] = NULL;
if (default_actionlists[i]) default_actionlists[i]->unref();
default_actionlists[i] = NULL;
}
if (ids && ls) {
list<ActionRegex *>::iterator it = ls->begin();
for (; it != ls->end(); it++) {
if ((actionlists[WIN_STATE_PASSIVE] =
(*it)->match(ids, WIN_STATE_PASSIVE, window_name))) {
break;
}
}
for (it = ls->begin(); it != ls->end(); it++) {
if ((actionlists[WIN_STATE_ACTIVE] =
(*it)->match(ids, WIN_STATE_ACTIVE, window_name))) {
break;
}
}
for (it = ls->begin(); it != ls->end(); it++) {
if ((actionlists[WIN_STATE_HOVER] =
(*it)->match(ids, WIN_STATE_HOVER, window_name))) {
break;
}
}
for (it = ls->begin(); it != ls->end(); it++) {
if ((actionlists[WIN_STATE_PRESSED] =
(*it)->match(ids, WIN_STATE_PRESSED, window_name))) {
break;
}
}
}
if (! actionlists[WIN_STATE_PASSIVE])
actionlists[WIN_STATE_PASSIVE] = (*ws->actionlists.begin())->ref();
for (int i = 0; i < WIN_STATE_LAST; i++) {
if (actionlists[i])
default_actionlists[i] = actionlists[i]->ref();
}
if (type == EdgeType) {
if (actionlists[WIN_STATE_PASSIVE]->actionlist.empty())
XUnmapWindow(ws->display, id);
else
XMapWindow(ws->display, id);
}
}
bool AWindowObject::handleEvent(XEvent *event, EventDetail *ed) {
bool status = false;
ActionList *al = actionlists[
STATE_FROM_MASK_AND_LIST(window_state_mask, actionlists)]->ref();
list<Action *>::iterator it = al->actionlist.begin();
list<Action *>::iterator end_it = al->actionlist.end();
for (; it != end_it; ++it) {
if ((*it)->match(ed)) {
Action *action = (*it)->ref();
if (! action->replay) status = true;
if (action->delay) {
Interrupt *i = new Interrupt(action, event, id);
ws->waimea->timer->addInterrupt(i);
} else {
if (action->timer_id &&
(! ws->waimea->timer->exitsInterrupt(action->timer_id)))
return status;
((*this).*(action->func))(event, action);
}
action->unref();
}
}
al->unref();
return status;
}
void AWindowObject::evalState(EventDetail *ed) {
DWindowObject *dwo = NULL;
WaWindow *wa = NULL;
int tmp_state = window_state_mask;
if (ed) {
switch (ed->type) {
case FocusIn:
if (type == WindowType) {
wa = (WaWindow *) this;
wa->frame->evalState(ed);
tmp_state |= WIN_STATE_ACTIVE_MASK;
} else {
tmp_state |= WIN_STATE_ACTIVE_MASK;
if (type & ANY_DECOR_WINDOW_TYPE) {
dwo = (DWindowObject *) this;
map<int, SubWindowObject *>::iterator it =
dwo->subs.begin();
for (; it != dwo->subs.end(); it++)
((*it).second)->evalState(ed);
}
}
break;
case FocusOut:
if (type == WindowType) {
wa = (WaWindow *) this;
wa->frame->evalState(ed);
bool merged_has_focus = false;
list<WaWindow *>::iterator it;
list<WaWindow *>::iterator it_end;
if (wa->master) {
it_end = wa->master->merged.end();
if (wa->master->id == ws->waimea->prefocus) {
merged_has_focus = true;
it = wa->master->merged.end();
} else
it = wa->master->merged.begin();
} else {
it = wa->merged.begin();
it_end = wa->merged.end();
}
for (; it != it_end; it++)
if ((*it)->id == ws->waimea->prefocus) {
merged_has_focus = true;
break;
}
if (! merged_has_focus) {
wa->frame->evalState(ed);
if (wa->master)
wa->master->frame->evalState(ed);
}
tmp_state &= ~WIN_STATE_ACTIVE_MASK;
} else if (type == MenuItemType) {
if (((MenuItem *) this)->submenu &&
((MenuItem *) this)->submenu->mapped) {
tmp_state |= WIN_STATE_ACTIVE_MASK;
} else
tmp_state &= ~WIN_STATE_ACTIVE_MASK;
} else {
tmp_state &= ~WIN_STATE_ACTIVE_MASK;
if (type & ANY_DECOR_WINDOW_TYPE) {
dwo = (DWindowObject *) this;
map<int, SubWindowObject *>::iterator it =
dwo->subs.begin();
for (; it != dwo->subs.end(); it++)
((*it).second)->evalState(ed);
}
}
break;
case EnterNotify:
tmp_state |= WIN_STATE_HOVER_MASK;
break;
case LeaveNotify:
tmp_state &= ~WIN_STATE_HOVER_MASK;
break;
case ButtonPress:
tmp_state |= WIN_STATE_PRESSED_MASK;
break;
case ButtonRelease:
tmp_state &= ~WIN_STATE_PRESSED_MASK;
break;
case SubmenuMapNotify:
if (type == MenuItemType)
tmp_state |= WIN_STATE_ACTIVE_MASK;
break;
case SubmenuUnmapNotify:
if (type == MenuItemType)
if (! ((MenuItem *) this)->focused)
tmp_state &= ~WIN_STATE_ACTIVE_MASK;
break;
default:
break;
}
}
ActionList *old_current_actionlist = NULL;
wa = NULL;
if (type == WindowType) {
wa = (WaWindow *) this;
old_current_actionlist = wa->actionlists[
STATE_FROM_MASK_AND_LIST(window_state_mask, wa->actionlists)];
}
Style *old_current_style = NULL;
dwo = NULL;
if (type & ANY_DECOR_WINDOW_TYPE) {
dwo = (DWindowObject *) this;
old_current_style = dwo->styles[
STATE_FROM_MASK_AND_LIST(window_state_mask, dwo->styles)];
}
window_state_mask = tmp_state;
if (wa) {
ActionList *new_current_actionlist = wa->actionlists[
STATE_FROM_MASK_AND_LIST(window_state_mask, wa->actionlists)];
if (new_current_actionlist != old_current_actionlist)
wa->updateGrabs();
}
if (dwo) {
bool pos_change = false;
bool size_change = false;
Style *new_current_style = dwo->styles[
STATE_FROM_MASK_AND_LIST(window_state_mask, dwo->styles)];
if (new_current_style != old_current_style) {
DWIN_RENDER_GET(dwo);
if (dwo->style) dwo->style->unref();
dwo->style = (Style *) new_current_style->ref();
dwo->commonStyleUpdate();
ws->styleDiff(new_current_style, old_current_style,
&pos_change, &size_change);
dwo->styleUpdate(pos_change, size_change);
DWIN_RENDER_RELEASE(dwo);
}
}
}
WaWindow *AWindowObject::getWindow(void) {
switch (type) {
case WindowType:
return (WaWindow *) this;
break;
case WindowFrameType:
return ((WaFrameWindow *) this)->wa;
break;
case SubwindowType:
switch (((DWindowObject *) this)->decor_root->type) {
case WindowFrameType:
return (WaWindow *)
((WaFrameWindow *)
((DWindowObject *) this)->decor_root)->wa;
default:
return (WaWindow *) 0;
}
break;
case MenuItemType: {
AWindowObject *m_awo = (AWindowObject *)
ws->waimea->findWin(((MenuItem *) this)->menu->a_id,
ANY_ACTION_WINDOW_TYPE);
if (m_awo && m_awo->type != MenuItemType)
return m_awo->getWindow();
}
default:
return (WaWindow *) 0;
}
}
WaScreen *AWindowObject::getScreen(void) {
switch (type) {
case RootType:
return (WaScreen *) this;
break;
default:
return (WaScreen *) 0;
}
}
MenuItem *AWindowObject::getMenuItem(void) {
switch (type) {
case MenuItemType:
return (MenuItem *) this;
break;
default:
return (MenuItem *) 0;
}
}
DockappHandler *AWindowObject::getDockHandler(void) {
switch (type) {
case DockHandlerType:
return (DockappHandler *) this;
break;
case DockAppType:
return ((Dockapp *) this)->dh;
break;
default:
return (DockappHandler *) 0;
}
}
Dockapp *AWindowObject::getDockapp(void) {
switch (type) {
case DockAppType:
return (Dockapp *) this;
break;
default:
return (Dockapp *) 0;
}
}
void AWindowObject::nop(XEvent *, Action *) {}
void AWindowObject::showInfo(XEvent *, Action *a) {
ws->showInfoMessage(__FUNCTION__, a->param? a->param: "");
}
void AWindowObject::showWarning(XEvent *, Action *a) {
ws->showWarningMessage(__FUNCTION__, a->param? a->param: "");
}
void AWindowObject::exec(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
if (! fork()) {
setsid();
putenv(ws->displaystring);
execl("/bin/sh", "/bin/sh", "-c", a->param, NULL);
exit(0);
}
}
void AWindowObject::doing(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
char *str = WA_STRDUP(a->param);
Tst<char *> *attr;
attr = short_do_string_to_tst(str);
Doing *doing = new Doing(ws);
doing->applyAttributes(NULL, attr);
ws->waimea->eh->doings.push_back(doing);
delete attr;
delete [] str;
}
void AWindowObject::stopTimer(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
int timer_id = (int) (unsigned int) atoi(a->param);
ws->waimea->timer->removeInterrupt(timer_id);
}
void AWindowObject::waexit(XEvent *, Action *) {
quit(EXIT_SUCCESS);
}
void AWindowObject::warestart(XEvent *, Action *a) {
restart(a->param);
}
void AWindowObject::setActionFile(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
if (ws->config.action_file) delete [] ws->config.action_file;
ws->config.action_file = WA_STRDUP(a->param);
}
void AWindowObject::setStyleFile(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
if (ws->config.style_file) delete [] ws->config.style_file;
ws->config.style_file = WA_STRDUP(a->param);
}
void AWindowObject::setMenuFile(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
if (ws->config.menu_file) delete [] ws->config.menu_file;
ws->config.menu_file = WA_STRDUP(a->param);
}
void AWindowObject::reloadWithActionFile(XEvent *, Action *a) {
setActionFile(NULL, a);
ws->reload();
}
void AWindowObject::reloadWithStyleFile(XEvent *, Action *a) {
setStyleFile(NULL, a);
ws->reload();
}
void AWindowObject::reloadWithMenuFile(XEvent *, Action *a) {
setMenuFile(NULL, a);
ws->reload();
}
void AWindowObject::reload(XEvent *, Action *) {
ws->reload();
}
void AWindowObject::taskSwitcher(XEvent *, Action *) {
ws->taskSwitcher();
}
void AWindowObject::nextTask(XEvent *, Action *) {
ws->nextTask();
}
void AWindowObject::previousTask(XEvent *, Action *) {
ws->previousTask();
}
void AWindowObject::goToDesktop(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
ws->goToDesktop((unsigned int) atoi(a->param));
}
void AWindowObject::nextDesktop(XEvent *, Action *) {
ws->nextDesktop();
}
void AWindowObject::previousDesktop(XEvent *, Action *) {
ws->previousDesktop();
}
void AWindowObject::pointerRelativeWarp(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
ws->pointerRelativeWarp(a->param);
}
void AWindowObject::pointerFixedWarp(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
ws->pointerFixedWarp(a->param);
}
void AWindowObject::viewportLeft(XEvent *, Action *) {
ws->moveViewport(WestDirection);
}
void AWindowObject::viewportRight(XEvent *, Action *) {
ws->moveViewport(EastDirection);
}
void AWindowObject::viewportUp(XEvent *, Action *) {
ws->moveViewport(NorthDirection);
}
void AWindowObject::viewportDown(XEvent *, Action *) {
ws->moveViewport(SouthDirection);
}
void AWindowObject::viewportRelativeMove(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
ws->viewportRelativeMove(a->param);
}
void AWindowObject::viewportFixedMove(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
ws->viewportFixedMove(a->param);
}
void AWindowObject::startViewportMove(XEvent *e, Action *) {
e->xany.window = id;
ws->startViewportMove();
}
void AWindowObject::mapMenu(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
Menu *menu = ws->getMenuNamed(a->param);
if (menu) menu->map(this, false, false);
}
void AWindowObject::remapMenu(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
Menu *menu = ws->getMenuNamed(a->param);
if (menu) menu->map(this, false, true);
}
void AWindowObject::mapMenuFocused(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
Menu *menu = ws->getMenuNamed(a->param);
if (menu) menu->map(this, true, false);
}
void AWindowObject::remapMenuFocused(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
Menu *menu = ws->getMenuNamed(a->param);
if (menu) menu->map(this, true, true);
}
void AWindowObject::unmapMenu(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
Menu *menu = ws->getMenuNamed(a->param);
if (menu) menu->unmap();
}
void AWindowObject::setActionList(int state, Action *a) {
ActionList *new_al = NULL;
if ((! a) || (! a->param)) new_al = default_actionlists[state];
if (! new_al) {
if (a->pointer.actionlist)
new_al = a->pointer.actionlist;
new_al = a->pointer.actionlist = ws->getActionListNamed(a->param);
}
if (new_al) {
if (actionlists[state])
actionlists[state]->unref();
actionlists[state] = new_al->ref();
if (type == WindowType) ((WaWindow *) this)->updateGrabs();
}
}
void AWindowObject::setPassiveActionList(XEvent *, Action *a) {
setActionList(WIN_STATE_PASSIVE, a);
}
void AWindowObject::setActiveActionList(XEvent *, Action *a) {
setActionList(WIN_STATE_ACTIVE, a);
}
void AWindowObject::setHoverActionList(XEvent *, Action *a) {
setActionList(WIN_STATE_HOVER, a);
}
void AWindowObject::setPressedActionList(XEvent *, Action *a) {
setActionList(WIN_STATE_PRESSED, a);
}
void AWindowObject::defaultPassiveActionList(XEvent *, Action *) {
setActionList(WIN_STATE_PASSIVE, NULL);
}
void AWindowObject::defaultActiveActionList(XEvent *, Action *) {
setActionList(WIN_STATE_ACTIVE, NULL);
}
void AWindowObject::defaultHoverActionList(XEvent *, Action *) {
setActionList(WIN_STATE_HOVER, NULL);
}
void AWindowObject::defaultPressedActionList(XEvent *, Action *) {
setActionList(WIN_STATE_PRESSED, NULL);
}
void AWindowObject::setStyle(int state, Action *a) {
DWindowObject *dwo;
if (type & ANY_DECOR_WINDOW_TYPE)
dwo = (DWindowObject *) this;
else {
WARNING << "not a decorative window" << endl;
return;
}
Style *new_s = NULL;
if ((! a) || (! a->param)) new_s = dwo->default_styles[state];
else {
if (a->pointer.style)
new_s = a->pointer.style;
else
new_s = a->pointer.style = ws->getStyleNamed(a->param);
}
if (new_s) {
Style *old_style = dwo->styles[state];
Style *old_current_style = dwo->styles[
STATE_FROM_MASK_AND_LIST(window_state_mask, dwo->styles)];
DWIN_RENDER_GET(dwo);
dwo->styles[state] = (Style *) new_s->ref();
bool pos_change = false;
bool size_change = false;
Style *new_current_style = dwo->styles[
STATE_FROM_MASK_AND_LIST(window_state_mask, dwo->styles)];
if (dwo->style) dwo->style->unref();
dwo->style = (Style *) new_current_style->ref();
if (new_current_style != old_current_style) {
dwo->commonStyleUpdate();
ws->styleDiff(new_current_style, old_current_style,
&pos_change, &size_change);
dwo->styleUpdate(pos_change, size_change);
}
if (old_style)
old_style->unref();
DWIN_RENDER_RELEASE(dwo);
}
}
void AWindowObject::setPassiveStyle(XEvent *, Action *a) {
setStyle(WIN_STATE_PASSIVE, a);
}
void AWindowObject::setActiveStyle(XEvent *, Action *a) {
setStyle(WIN_STATE_ACTIVE, a);
}
void AWindowObject::setHoverStyle(XEvent *, Action *a) {
setStyle(WIN_STATE_HOVER, a);
}
void AWindowObject::setPressedStyle(XEvent *, Action *a) {
setStyle(WIN_STATE_PRESSED, a);
}
void AWindowObject::defaultPassiveStyle(XEvent *, Action *) {
setStyle(WIN_STATE_PASSIVE, NULL);
}
void AWindowObject::defaultActiveStyle(XEvent *, Action *) {
setStyle(WIN_STATE_ACTIVE, NULL);
}
void AWindowObject::defaultHoverStyle(XEvent *, Action *) {
setStyle(WIN_STATE_HOVER, NULL);
}
void AWindowObject::defaultPressedStyle(XEvent *, Action *) {
setStyle(WIN_STATE_PRESSED, NULL);
}
void AWindowObject::setCursor(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
Cursor c;
if (a->pointer.cursor) c = a->pointer.cursor;
else c = ws->waimea->cursor->getCursor(a->param);
if (c) XDefineCursor(ws->display, id, c);
}
void AWindowObject::defaultCursor(XEvent *, Action *) {
DWindowObject *dwo;
if (! (type & ANY_DECOR_WINDOW_TYPE)) return;
dwo = (DWindowObject *) this;
if (dwo->style->cursor)
XDefineCursor(ws->display, id, dwo->style->cursor);
}
void AWindowObject::endMoveResize(XEvent *, Action *) {
ws->waimea->eh->move_resize = EndMoveResizeType;
}
void AWindowObject::moveFocusToClosestNorthWindow(XEvent *, Action *) {
ws->findClosestWindow(NorthDirection);
}
void AWindowObject::moveFocusToClosestSouthWindow(XEvent *, Action *) {
ws->findClosestWindow(SouthDirection);
}
void AWindowObject::moveFocusToClosestWestWindow(XEvent *, Action *) {
ws->findClosestWindow(WestDirection);
}
void AWindowObject::moveFocusToClosestEastWindow(XEvent *, Action *) {
ws->findClosestWindow(EastDirection);
}
void AWindowObject::readAdditionalConfig(XEvent *, Action *a) {
if (! a->param) PARAM_WARNING;
Parser *parser = new Parser(ws);
parser->pushElementHandler(new CfgElementHandler(parser));
RENDER_GET;
parser->parseFile(a->param, false);
RENDER_RELEASE;
}
void AWindowObject::focusRoot(XEvent *, Action *) {
ws->waimea->focusNew(ws->id, false);
}
void AWindowObject::windowRaise(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->raise();
else ACTION_WARNING;
}
void AWindowObject::windowLower(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->lower();
else ACTION_WARNING;
}
void AWindowObject::windowFocus(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) ws->waimea->focusNew(w->id);
else ACTION_WARNING;
}
void AWindowObject::windowRaiseFocus(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) {
w->raise();
ws->waimea->focusNew(w->id, true);
}
else ACTION_WARNING;
}
void AWindowObject::windowStartMove(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->move(e);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeUpRight(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, EastResizeTypeMask |
NorthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeDownRight(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, EastResizeTypeMask |
SouthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeRight(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, EastResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeUpLeft(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, WestResizeTypeMask |
NorthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeDownLeft(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, WestResizeTypeMask |
SouthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeLeft(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, WestResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeUp(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, NorthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeDown(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resize(e, SouthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartResizeSmart(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeSmart(e);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueMove(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->moveOpaque(e);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeUpRight(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, EastResizeTypeMask |
NorthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeDownRight(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, EastResizeTypeMask |
SouthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeRight(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, EastResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeUpLeft(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, WestResizeTypeMask |
NorthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeDownLeft(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, WestResizeTypeMask |
SouthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeLeft(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, WestResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeUp(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, NorthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeDown(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeOpaque(e, SouthResizeTypeMask);
else ACTION_WARNING;
}
void AWindowObject::windowStartOpaqueResizeSmart(XEvent *e, Action *) {
e->xany.window = id;
WaWindow *w;
if ((w = getWindow())) w->resizeSmartOpaque(e);
else ACTION_WARNING;
}
void AWindowObject::windowMoveResize(XEvent *e, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->moveResize(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowMoveResizeVirtual(XEvent *e, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->moveResizeVirtual(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowMoveToPointer(XEvent *e, Action *) {
WaWindow *w;
if ((w = getWindow())) w->moveWindowToPointer(e);
else ACTION_WARNING;
}
void AWindowObject::windowMoveToSmartPlace(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->moveWindowToSmartPlace();
else ACTION_WARNING;
}
void AWindowObject::windowDesktopMask(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->desktopMask(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowJoinDesktop(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->joinDesktop(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowPartDesktop(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->partDesktop(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowPartCurrentDesktop(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->partCurrentDesktop();
else ACTION_WARNING;
}
void AWindowObject::windowJoinAllDesktops(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->joinAllDesktops();
else ACTION_WARNING;
}
void AWindowObject::windowPartAllDesktopsExceptCurrent(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->partAllDesktopsExceptCurrent();
else ACTION_WARNING;
}
void AWindowObject::windowPartCurrentJoinDesktop(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->partCurrentJoinDesktop(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowCloneMergeWithWindow(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->cloneMergeWithWindow(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowVertMergeWithWindow(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->vertMergeWithWindow(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowHorizMergeWithWindow(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->horizMergeWithWindow(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowExplode(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->explode();
else ACTION_WARNING;
}
void AWindowObject::windowMergedToFront(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->toFront();
else ACTION_WARNING;
}
void AWindowObject::windowUnMerge(XEvent *e, Action *) {
WaWindow *w;
if ((w = getWindow())) w->unMergeMaster(e);
else ACTION_WARNING;
}
void AWindowObject::windowSetMergeMode(XEvent *, Action *a) {
WaWindow *w;
if (! a->param) PARAM_WARNING;
if ((w = getWindow())) w->setMergeMode(a->param);
else ACTION_WARNING;
}
void AWindowObject::windowNextMergeMode(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->nextMergeMode();
else ACTION_WARNING;
}
void AWindowObject::windowPrevMergeMode(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->prevMergeMode();
else ACTION_WARNING;
}
void AWindowObject::windowClose(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->close();
else ACTION_WARNING;
}
void AWindowObject::windowKill(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->kill();
else ACTION_WARNING;
}
void AWindowObject::windowCloseKill(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->closeKill();
else ACTION_WARNING;
}
void AWindowObject::windowShade(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->shade();
else ACTION_WARNING;
}
void AWindowObject::windowUnShade(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->unShade();
else ACTION_WARNING;
}
void AWindowObject::windowToggleShade(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->toggleShade();
else ACTION_WARNING;
}
void AWindowObject::windowMaximize(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->maximize();
else ACTION_WARNING;
}
void AWindowObject::windowUnMaximize(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->unMaximize();
else ACTION_WARNING;
}
void AWindowObject::windowToggleMaximize(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->toggleMaximize();
else ACTION_WARNING;
}
void AWindowObject::windowMinimize(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->minimize();
else ACTION_WARNING;
}
void AWindowObject::windowUnMinimize(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->unMinimize();
else ACTION_WARNING;
}
void AWindowObject::windowSticky(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->sticky();
else ACTION_WARNING;
}
void AWindowObject::windowUnSticky(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->unSticky();
else ACTION_WARNING;
}
void AWindowObject::windowToggleSticky(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->toggleSticky();
else ACTION_WARNING;
}
void AWindowObject::windowFullscreenOn(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->fullscreenOn();
else ACTION_WARNING;
}
void AWindowObject::windowFullscreenOff(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->fullscreenOff();
else ACTION_WARNING;
}
void AWindowObject::windowFullscreenToggle(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->fullscreenToggle();
else ACTION_WARNING;
}
void AWindowObject::windowToggleMinimize(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->toggleMinimize();
else ACTION_WARNING;
}
void AWindowObject::windowDecorTitleOn(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorTitleOn();
else ACTION_WARNING;
}
void AWindowObject::windowDecorTitleOff(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorTitleOff();
else ACTION_WARNING;
}
void AWindowObject::windowDecorTitleToggle(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorTitleToggle();
else ACTION_WARNING;
}
void AWindowObject::windowDecorBorderOn(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorBorderOn();
else ACTION_WARNING;
}
void AWindowObject::windowDecorBorderOff(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorBorderOff();
else ACTION_WARNING;
}
void AWindowObject::windowDecorBorderToggle(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorBorderToggle();
else ACTION_WARNING;
}
void AWindowObject::windowDecorHandlesOn(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorHandlesOn();
else ACTION_WARNING;
}
void AWindowObject::windowDecorHandlesOff(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorHandlesOff();
else ACTION_WARNING;
}
void AWindowObject::windowDecorHandlesToggle(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorHandlesToggle();
else ACTION_WARNING;
}
void AWindowObject::windowDecorAllOn(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorAllOn();
else ACTION_WARNING;
}
void AWindowObject::windowDecorAllOff(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->decorAllOff();
else ACTION_WARNING;
}
void AWindowObject::windowAlwaysOnTopOn(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->alwaysontopOn();
else ACTION_WARNING;
}
void AWindowObject::windowAlwaysOnTopOff(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->alwaysontopOff();
else ACTION_WARNING;
}
void AWindowObject::windowAlwaysOnTopToggle(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->alwaysontopToggle();
else ACTION_WARNING;
}
void AWindowObject::windowAlwaysAtBottomOn(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->alwaysatbottomOn();
else ACTION_WARNING;
}
void AWindowObject::windowAlwaysAtBottomOff(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->alwaysatbottomOff();
else ACTION_WARNING;
}
void AWindowObject::windowAlwaysAtBottomToggle(XEvent *, Action *) {
WaWindow *w;
if ((w = getWindow())) w->alwaysatbottomToggle();
else ACTION_WARNING;
}
void AWindowObject::menuMapSubmenu(XEvent *, Action *a) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->mapSubmenu(a->param, false);
else ACTION_WARNING;
}
void AWindowObject::menuUnLink(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->unLink();
else ACTION_WARNING;
}
void AWindowObject::menuRemapSubmenu(XEvent *, Action *a) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->mapSubmenu(a->param, true);
else ACTION_WARNING;
}
void AWindowObject::menuUnMap(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->unmap();
else ACTION_WARNING;
}
void AWindowObject::menuUnMapSubmenus(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->unmapSubmenus();
else ACTION_WARNING;
}
void AWindowObject::menuUnMapOtherSubmenus(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->unmapOtherSubmenus();
else ACTION_WARNING;
}
void AWindowObject::menuUnMapTree(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->unmapTree();
else ACTION_WARNING;
}
void AWindowObject::menuAction(XEvent *e, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->perform(e);
else ACTION_WARNING;
}
void AWindowObject::menuNextItem(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->nextItem();
else ACTION_WARNING;
}
void AWindowObject::menuPreviousItem(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->previousItem();
else ACTION_WARNING;
}
void AWindowObject::menuStartMove(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->move();
else ACTION_WARNING;
}
void AWindowObject::menuStartOpaqueMove(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) mi->moveOpaque();
else ACTION_WARNING;
}
void AWindowObject::menuRaise(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) {
ws->raiseWindow(mi->menu->id, false);
mi->menu->raiseSubmenus();
ws->restackWindows();
}
else ACTION_WARNING;
}
void AWindowObject::menuLower(XEvent *, Action *) {
MenuItem *mi;
if ((mi = getMenuItem())) {
mi->menu->lowerSubmenus();
ws->lowerWindow(mi->menu->id, false);
ws->restackWindows();
}
else ACTION_WARNING;
}
void AWindowObject::dockappHandlerSetInWorkspace(XEvent *, Action *) {
DockappHandler *dh;
if ((dh = getDockHandler())) {
dh->inworkspace = true;
dh->update();
} else ACTION_WARNING;
}
void AWindowObject::dockappHandlerSetNotInWorkspace(XEvent *, Action *) {
DockappHandler *dh;
if ((dh = getDockHandler())) {
dh->inworkspace = false;
dh->update();
} else ACTION_WARNING;
}
void AWindowObject::dockappHandlerRaise(XEvent *, Action *) {
DockappHandler *d;
if ((d = getDockHandler())) ws->raiseWindow(d->id);
else ACTION_WARNING;
}
void AWindowObject::dockappHandlerLower(XEvent *, Action *) {
DockappHandler *d;
if ((d = getDockHandler())) ws->lowerWindow(d->id);
else ACTION_WARNING;
}
void AWindowObject::dockappAddToHandler(XEvent *, Action *a) {
Dockapp *d;
if ((d = getDockapp())) {
ws->addDockapp(d, a->param);
} else ACTION_WARNING;
}
void AWindowObject::dockappSetPrio(XEvent *, Action *a) {
Dockapp *d;
if ((d = getDockapp())) {
if (! a->param) d->prio = 0;
else d->prio = atoi(a->param);
if (d->dh) {
d->dh->dockapp_list.remove(d);
list<Dockapp *>::iterator dit = d->dh->dockapp_list.begin();
for (; dit != d->dh->dockapp_list.end() &&
(*dit)->prio <= d->prio; dit++);
d->dh->dockapp_list.insert(dit, d);
d->dh->update();
}
d->prio_set = true;
ws->net->setDockappPrio(d);
} else ACTION_WARNING;
}
void AWindowObject::setStackingLayer(XEvent *, Action *a) {
MenuItem *mi;
DockappHandler *d;
if (! a->param) PARAM_WARNING;
StackingType st = NormalStackingType;
if (!strcmp(a->param, "alwaysontop"))
st = AlwaysOnTopStackingType;
else if (!strcmp(a->param, "alwaysatbottom"))
st = AlwaysAtBottomStackingType;
if ((mi = getMenuItem())) {
mi->menu->setStacking(st);
ws->restackWindows();
}
else if ((d = getDockHandler())) {
d->setStacking(st);
ws->restackWindows();
} else ACTION_WARNING;
}
Doing::Doing(WaScreen *_ws) {
param = NULL;
wreg = NULL;
ws = _ws;
target_type = WindowType;
func = NULL;
multiple = true;
}
Doing::~Doing(void) {
if (param) delete [] param;
if (wreg) delete wreg;
}
static const struct WindowTypeMap {
char *name;
int type;
} window_type_map[] = {
{ "root", RootType },
{ "window", WindowType },
{ "menu", MenuType },
{ "menuitem", MenuItemType },
{ "dockappholder", DockHandlerType },
{ "dockapp", DockAppType },
{ "screenedge", EdgeType }
};
void Doing::applyAttributes(Parser *parser, Tst<char *> *attr) {
char *value = parser->attrGetString(attr, "target", NULL);
if (value) {
Tst<int>::iterator it = window_type_tst->find(value);
if (it != window_type_tst->end()) target_type = *it;
}
value = parser->attrGetString(attr, "function", NULL);
if (value) {
Tst<ActionFunc>::iterator it = actionfunction_tst->find(value);
if (it != actionfunction_tst->end()) func = *it;
}
value = parser->attrGetString(attr, "parameter", NULL);
if (value) {
param = WA_STRDUP(value);
}
value = parser->attrGetString(attr, "window", NULL);
wreg = new WindowRegex(WIN_STATE_LAST, value);
parser->attrGetWindowregexContent(attr, wreg);
value = parser->attrGetString(attr, "applies", NULL);
if (value)
if (! strcasecmp(value, "firstfound"))
multiple = false;
}
void Doing::envoke(void) {
if (func) {
list<AWindowObject *> awos;
ws->getRegexTargets(wreg, target_type, multiple, &awos);
if (! awos.empty()) {
Action *action = new Action;
if (param) action->param = param;
else action->param = NULL;
list<AWindowObject *>::iterator ait = awos.begin();
for (; ait != awos.end(); ait++)
((*(*ait)).*(func))(NULL, action);
action->param = NULL;
action->unref();
awos.clear();
}
}
}
Tst<char *> *short_do_string_to_tst(char *s) {
Tst<char *> *tst = new Tst<char *>;
if (! s || *s == '\0') return tst;
for (;;) {
char *name = s;
char *value = "";
for (; *s != '\0' && *s != '='; s++);
if (*s == '\0') break;
else *s++ = '\0';
value = s;
tst->insert(name, value);
for (; *s != '\0' && *s != ':'; s++);
if (*s == '\0') break;
else *s++ = '\0';
}
return tst;
}
static const struct ActionFunctionMap {
char *name;
ActionFunc function;
} actionfunction_map[] = {
{ "nop", &AWindowObject::nop },
{ "showinfo", &AWindowObject::showInfo },
{ "showwarning", &AWindowObject::showWarning },
{ "exec", &AWindowObject::exec },
{ "do", &AWindowObject::doing },
{ "stoptimer", &AWindowObject::stopTimer },
{ "exit", &AWindowObject::waexit },
{ "restart", &AWindowObject::warestart },
{ "setactionfile", &AWindowObject::setActionFile },
{ "setstylefile", &AWindowObject::setStyleFile },
{ "setmenufile", &AWindowObject::setMenuFile },
{ "reloadwithactionfile", &AWindowObject::reloadWithActionFile },
{ "reloadwithstylefile", &AWindowObject::reloadWithStyleFile },
{ "reloadwithmenufile", &AWindowObject::reloadWithMenuFile },
{ "reload", &AWindowObject::reload },
{ "taskswitcher", &AWindowObject::taskSwitcher },
{ "nexttask", &AWindowObject::nextTask },
{ "previoustask", &AWindowObject::previousTask },
{ "gotodesktop", &AWindowObject::goToDesktop },
{ "nextdesktop", &AWindowObject::nextDesktop },
{ "previousdesktop", &AWindowObject::previousDesktop },
{ "pointerrelativewarp", &AWindowObject::pointerRelativeWarp },
{ "pointerfixedwarp", &AWindowObject::pointerFixedWarp },
{ "viewportleft", &AWindowObject::viewportLeft },
{ "viewportright", &AWindowObject::viewportRight },
{ "viewportup", &AWindowObject::viewportUp },
{ "viewportdown", &AWindowObject::viewportDown },
{ "viewportrelativemove", &AWindowObject::viewportRelativeMove },
{ "viewportfixedmove", &AWindowObject::viewportFixedMove },
{ "startviewportmove", &AWindowObject::startViewportMove },
{ "setpassiveactionlist", &AWindowObject::setPassiveActionList },
{ "setactiveactionlist", &AWindowObject::setActiveActionList },
{ "sethoveractionlist", &AWindowObject::setHoverActionList },
{ "setpressedactionlist", &AWindowObject::setPressedActionList },
{ "defaultpassiveactionlist", &AWindowObject::defaultPassiveActionList },
{ "defaultactiveactionlist", &AWindowObject::defaultActiveActionList },
{ "defaulthoveractionlist", &AWindowObject::defaultHoverActionList },
{ "defaultpressedactionlist", &AWindowObject::defaultPressedActionList },
{ "setpassivestyle", &AWindowObject::setPassiveStyle },
{ "setactivestyle", &AWindowObject::setActiveStyle },
{ "sethoverstyle", &AWindowObject::setHoverStyle },
{ "setpressedstyle", &AWindowObject::setPressedStyle },
{ "defaultpassivestyle", &AWindowObject::defaultPassiveStyle },
{ "defaultactivestyle", &AWindowObject::defaultActiveStyle },
{ "defaulthoverstyle", &AWindowObject::defaultHoverStyle },
{ "defaultpressedstyle", &AWindowObject::defaultPressedStyle },
{ "setcursor", &AWindowObject::setCursor },
{ "defaultcursor", &AWindowObject::defaultCursor },
{ "mapmenu", &AWindowObject::mapMenu },
{ "remapmenu", &AWindowObject::remapMenu },
{ "mapmenufocused", &AWindowObject::mapMenuFocused },
{ "remapmenufocused", &AWindowObject::remapMenuFocused },
{ "unmapmenu", &AWindowObject::unmapMenu },
{ "endmoveresize", &AWindowObject::endMoveResize },
{ "movefocustoclosestnorthwindow",
&AWindowObject::moveFocusToClosestNorthWindow },
{ "movefocustoclosestsouthwindow",
&AWindowObject::moveFocusToClosestSouthWindow },
{ "movefocustoclosestwestwindow",
&AWindowObject::moveFocusToClosestWestWindow },
{ "movefocustoclosesteastwindow",
&AWindowObject::moveFocusToClosestEastWindow },
{ "readadditionalconfig", &AWindowObject::readAdditionalConfig },
{ "focusroot", &AWindowObject::focusRoot },
{ "windowraise", &AWindowObject::windowRaise },
{ "windowlower", &AWindowObject::windowLower },
{ "windowfocus", &AWindowObject::windowFocus },
{ "windowraisefocus", &AWindowObject::windowRaiseFocus },
{ "windowstartmove", &AWindowObject::windowStartMove },
{ "windowstartresizedownright",
&AWindowObject::windowStartResizeDownRight },
{ "windowstartresizeupright", &AWindowObject::windowStartResizeUpRight },
{ "windowstartresizeright", &AWindowObject::windowStartResizeRight },
{ "windowstartresizedownleft", &AWindowObject::windowStartResizeDownLeft },
{ "windowstartresizeupleft", &AWindowObject::windowStartResizeUpLeft },
{ "windowstartresizeleft", &AWindowObject::windowStartResizeLeft },
{ "windowstartresizedown", &AWindowObject::windowStartResizeDown },
{ "windowstartresizeup", &AWindowObject::windowStartResizeUp },
{ "windowstartresizesmart", &AWindowObject::windowStartResizeSmart },
{ "windowstartopaquemove", &AWindowObject::windowStartOpaqueMove },
{ "windowstartopaqueresizedownright",
&AWindowObject::windowStartOpaqueResizeDownRight },
{ "windowstartopaqueresizeupright",
&AWindowObject::windowStartOpaqueResizeUpRight },
{ "windowstartopaqueresizeright",
&AWindowObject::windowStartOpaqueResizeRight },
{ "windowstartopaqueresizedownleft",
&AWindowObject::windowStartOpaqueResizeDownLeft },
{ "windowstartopaqueresizeupleft",
&AWindowObject::windowStartOpaqueResizeUpLeft },
{ "windowstartopaqueresizeleft",
&AWindowObject::windowStartOpaqueResizeLeft },
{ "windowstartopaqueresizedown",
&AWindowObject::windowStartOpaqueResizeDown },
{ "windowstartopaqueresizeup", &AWindowObject::windowStartOpaqueResizeUp },
{ "windowstartopaqueresizesmart",
&AWindowObject::windowStartOpaqueResizeSmart },
{ "windowmoveresize", &AWindowObject::windowMoveResize },
{ "windowmoveresizevirtual", &AWindowObject::windowMoveResizeVirtual },
{ "windowmovetopointer", &AWindowObject::windowMoveToPointer },
{ "windowmovetosmartplace", &AWindowObject::windowMoveToSmartPlace },
{ "windowdesktopmask", &AWindowObject::windowDesktopMask },
{ "windowjoindesktop", &AWindowObject::windowJoinDesktop },
{ "windowpartdesktop", &AWindowObject::windowPartDesktop },
{ "windowpartcurrentdesktop", &AWindowObject::windowPartCurrentDesktop },
{ "windowjoinalldesktops", &AWindowObject::windowJoinAllDesktops },
{ "windowpartalldesktopsexceptcurrent",
&AWindowObject::windowPartAllDesktopsExceptCurrent },
{ "windowpartcurrentjoindesktop",
&AWindowObject::windowPartCurrentJoinDesktop },
{ "windowclonemergewithwindow",
&AWindowObject::windowCloneMergeWithWindow },
{ "windowvertmergewithwindow", &AWindowObject::windowVertMergeWithWindow },
{ "windowhorizmergewithwindow",
&AWindowObject::windowHorizMergeWithWindow },
{ "windowexplode", &AWindowObject::windowExplode },
{ "windowmergedtofront", &AWindowObject::windowMergedToFront },
{ "windowunmerge", &AWindowObject::windowUnMerge },
{ "windowsetmergemode", &AWindowObject::windowSetMergeMode },
{ "windownextmergemode", &AWindowObject::windowNextMergeMode },
{ "windowprevmergemode", &AWindowObject::windowPrevMergeMode },
{ "windowclose", &AWindowObject::windowClose },
{ "windowkill", &AWindowObject::windowKill },
{ "windowclosekill", &AWindowObject::windowCloseKill },
{ "windowshade", &AWindowObject::windowShade },
{ "windowunshade", &AWindowObject::windowUnShade },
{ "windowtoggleshade", &AWindowObject::windowToggleShade },
{ "windowmaximize", &AWindowObject::windowMaximize },
{ "windowunmaximize", &AWindowObject::windowUnMaximize },
{ "windowtogglemaximize", &AWindowObject::windowToggleMaximize },
{ "windowminimize", &AWindowObject::windowMinimize },
{ "windowunminimize", &AWindowObject::windowUnMinimize },
{ "windowsticky", &AWindowObject::windowSticky },
{ "windowunsticky", &AWindowObject::windowUnSticky },
{ "windowtogglesticky", &AWindowObject::windowToggleSticky },
{ "windowfullscreenon", &AWindowObject::windowFullscreenOn },
{ "windowfullscreenoff", &AWindowObject::windowFullscreenOff },
{ "windowfullscreenToggle", &AWindowObject::windowFullscreenToggle },
{ "windowtoggleminimize", &AWindowObject::windowToggleMinimize },
{ "windowdecortitleon", &AWindowObject::windowDecorTitleOn },
{ "windowdecortitleoff", &AWindowObject::windowDecorTitleOff },
{ "windowdecortitletoggle", &AWindowObject::windowDecorTitleToggle },
{ "windowdecorborderon", &AWindowObject::windowDecorBorderOn },
{ "windowdecorborderoff", &AWindowObject::windowDecorBorderOff },
{ "windowdecorbordertoggle", &AWindowObject::windowDecorBorderToggle },
{ "windowdecorhandleson", &AWindowObject::windowDecorHandlesOn },
{ "windowdecorhandlesoff", &AWindowObject::windowDecorHandlesOff },
{ "windowdecorhandlestoggle", &AWindowObject::windowDecorHandlesToggle },
{ "windowdecorallon", &AWindowObject::windowDecorAllOn },
{ "windowdecoralloff", &AWindowObject::windowDecorAllOff },
{ "windowalwaysontopon", &AWindowObject::windowAlwaysOnTopOn },
{ "windowalwaysontopoff", &AWindowObject::windowAlwaysOnTopOff },
{ "windowalwaysontoptoggle", &AWindowObject::windowAlwaysOnTopToggle },
{ "windowalwaysatbottomon", &AWindowObject::windowAlwaysAtBottomOn },
{ "windowalwaysatbottomoff", &AWindowObject::windowAlwaysAtBottomOff },
{ "windowalwaysatbottomtoggle",
&AWindowObject::windowAlwaysAtBottomToggle },
{ "menuunlink", &AWindowObject::menuUnLink },
{ "menumapsubmenu", &AWindowObject::menuMapSubmenu },
{ "menuunlink", &AWindowObject::menuUnLink },
{ "menumapsubmenu", &AWindowObject::menuMapSubmenu },
{ "menuremapsubmenu", &AWindowObject::menuRemapSubmenu },
{ "menuunmap", &AWindowObject::menuUnMap },
{ "menuunmapsubmenus", &AWindowObject::menuUnMapSubmenus },
{ "menuunmapothersubmenus", &AWindowObject::menuUnMapOtherSubmenus },
{ "menuunmaptree", &AWindowObject::menuUnMapTree },
{ "menuaction", &AWindowObject::menuAction },
{ "menunextitem", &AWindowObject::menuNextItem },
{ "menupreviousitem", &AWindowObject::menuPreviousItem },
{ "menuraise", &AWindowObject::menuRaise },
{ "menulower", &AWindowObject::menuLower },
{ "menustartmove", &AWindowObject::menuStartMove },
{ "menustartopaquemove", &AWindowObject::menuStartOpaqueMove },
{ "menusetstacking", &AWindowObject::setStackingLayer },
{ "dockappholdersetinworkspace",
&AWindowObject::dockappHandlerSetInWorkspace },
{ "dockappholdersetnotinworkspace",
&AWindowObject::dockappHandlerSetNotInWorkspace },
{ "dockappholderraise", &AWindowObject::dockappHandlerRaise },
{ "dockappholderlower", &AWindowObject::dockappHandlerLower },
{ "dockappholdersetstacking", &AWindowObject::setStackingLayer },
{ "dockappaddtoholder", &AWindowObject::dockappAddToHandler },
{ "dockappsetpriority", &AWindowObject::dockappSetPrio }
};
static const struct ClientWindowStateMap {
char *name;
long int state;
} client_window_state_map[] = {
{ "windowstatemove", StateMoveMask },
{ "windowstateresize", StateResizeMask },
{ "windowstatesticky", StateStickyMask },
{ "windowstateshaded", StateShadedMask },
{ "windowstatemaximized", StateMaximizedMask },
{ "windowstateminimized", StateMinimizedMask },
{ "windowstatefullscreen", StateFullscreenMask },
{ "windowstatedecortitle", StateDecorTitleMask },
{ "windowstatedecorborder", StateDecorBorderMask },
{ "windowstatedecorhandles", StateDecorHandlesMask },
{ "windowstatedecorall", StateDecorAllMask },
{ "windowstatealwaysontop", StateAlwaysOnTopMask },
{ "windowstatealwaysatbottom", StateAlwaysAtBottomMask },
{ "windowstatetransient", StateTransientMask },
{ "windowstategroupleader", StateGroupLeaderMask },
{ "windowstategroupmember", StateGroupMemberMask },
{ "windowstateurgent", StateUrgentMask },
{ "windowstatefocusable", StateFocusableMask },
{ "windowstatetasklist", StateTasklistMask },
{ "windowstateewmhdesktop", StateEwmhDesktopMask },
{ "windowstateewmhdock", StateEwmhDockMask },
{ "windowstateewmhtoolbar", StateEwmhToolbarMask },
{ "windowstateewmhmenu", StateEwmhMenuMask },
{ "windowstateewmhsplash", StateEwmhSplashMask },
{ "windowstateewmhdialog", StateEwmhDialogMask },
{ "windowstateusertime", StateUserTimeMask },
{ "windowstatepositioned", StatePositionedMask }
};
void action_create_tsts(void) {
int size, i;
actionfunction_tst = new Tst<ActionFunc>;
size = sizeof(actionfunction_map) / sizeof(ActionFunctionMap);
for (i = 0; i < size; i++)
actionfunction_tst->insert(actionfunction_map[i].name,
actionfunction_map[i].function);
client_window_state_tst = new Tst<long int>;
size = sizeof(client_window_state_map) / sizeof(ClientWindowStateMap);
for (i = 0; i < size; i++)
client_window_state_tst->insert(client_window_state_map[i].name,
client_window_state_map[i].state);
event_tst = new Tst<int>;
size = sizeof(event_map) / sizeof(EventMap);
for (i = 0; i < size; i++)
event_tst->insert(event_map[i].name, event_map[i].event);
window_type_tst = new Tst<int>;
size = sizeof(window_type_map) / sizeof(WindowTypeMap);
for (i = 0; i < size; i++)
window_type_tst->insert(window_type_map[i].name,
window_type_map[i].type);
}
syntax highlighted by Code2HTML, v. 0.9.1