From: Dana Jansens Date: Sat, 29 Jun 2002 23:50:04 +0000 (+0000) Subject: Configureable button mappings! X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=351a06655bdd7d440780b5bc5b255081c888044b;p=chaz%2Fopenbox Configureable button mappings! --- diff --git a/src/Input.cc b/src/Input.cc new file mode 100644 index 00000000..0c243ecc --- /dev/null +++ b/src/Input.cc @@ -0,0 +1,327 @@ +// -*- mode: C++; indent-tabs-mode: nil; -*- +// Input.cc for Blackbox - an X11 Window manager +// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry +// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif // HAVE_CONFIG_H + +#include "Input.hh" +#include "blackbox.hh" +#include "Window.hh" + +BInput::BInput(Blackbox *b) { + _blackbox = b; + _display = b->getXDisplay(); + + // hardcode blackbox's oldschool mouse bindings + + // buttons + add(Button1, 0, IconifyButtonClick, Iconify); + add(Button1, 0, CloseButtonClick, Close); + + add(Button1, 0, MaximizeButtonClick, ToggleMaximize); + add(Button1, 0, MaximizeButtonClick, Raise); + + add(Button2, 0, MaximizeButtonClick, ToggleMaximizeVert); + add(Button2, 0, MaximizeButtonClick, Raise); + + add(Button3, 0, MaximizeButtonClick, ToggleMaximizeHoriz); + add(Button3, 0, MaximizeButtonClick, Raise); + + // title-bar + + add(Button1, ControlMask, WindowTitlePress, ToggleShade); + add(Button2, 0, WindowTitlePress, Lower); + add(Button1, 0, WindowTitleDoublePress, ToggleShade); + + // mouse wheel + add(Button4, 0, WindowTitlePress, Shade); + add(Button5, 0, WindowTitlePress, Unshade); + + // drag moving + add(Button1, 0, WindowHandleDrag, BeginMove); + add(Button1, 0, WindowTitleDrag, BeginMove); + add(Button1, Mod1Mask, WindowDrag, BeginMove); + + // drag resizing + add(Button3, Mod1Mask, WindowDrag, BeginResizeRelative); + add(Button1, 0, WindowLeftGripDrag, BeginResizeLL); + add(Button1, 0, WindowRightGripDrag, BeginResizeLR); + + // window menu + add(Button3, 0, WindowTitlePress, ShowWindowMenu); + add(Button3, 0, WindowFramePress, ShowWindowMenu); + + // focus/raising + add(Button1, AnyModifier, WindowTitlePress, Raise); + add(Button1, AnyModifier, WindowTitlePress, Focus); + add(Button1, AnyModifier, WindowFramePress, Raise); + add(Button1, AnyModifier, WindowFramePress, Focus); +} + + +BInput::~BInput() { +} + + +void BInput::add(unsigned int button, unsigned int state, MouseEvent event, + Action action) { + _mousebind.push_back(MouseBinding(button, state, event, action)); +} + + +void BInput::add(unsigned int button, unsigned int state, Action action) { + _keybind.push_back(KeyBinding(button, state, action)); +} + + +void BInput::remove(unsigned int button, unsigned int state, MouseEvent event, + Action action) { + MouseBindingList::iterator it = _mousebind.begin(); + const MouseBindingList::iterator end = _mousebind.end(); + while (it != end) { + if (it->button == button && it->state == state && it->action == action && + it->event == event) { + MouseBindingList::iterator tmp = it; + ++it; + _mousebind.erase(tmp); + } else { + ++it; + } + } +} + + +void BInput::remove(unsigned int button, unsigned int state, Action action) { + KeyBindingList::iterator it = _keybind.begin(); + const KeyBindingList::iterator end = _keybind.end(); + while (it != end) { + if (it->button == button && it->state == state && it->action == action) { + ++it; + _keybind.erase(it); + } else { + ++it; + } + } +} + + +// execute a keyboard binding +bool BInput::doAction(BlackboxWindow *window, unsigned int keycode, + unsigned int state) const { + bool ret = False; + + KeyBindingList::const_iterator it = _keybind.begin(); + const KeyBindingList::const_iterator end = _keybind.end(); + for (; it != end; ++it) + if ((it->state == state || it->state == AnyModifier) && + it->button == keycode && it->action != NoAction) { + doAction(window, it->action); + ret = True; + } + return ret; +} + + +// determine if a keyboard binding exists +bool BInput::hasAction(unsigned int keycode, unsigned int state) const { + KeyBindingList::const_iterator it = _keybind.begin(); + const KeyBindingList::const_iterator end = _keybind.end(); + for (; it != end; ++it) + if ((it->state == state || it->state == AnyModifier) && + it->button == keycode && it->action != NoAction) + return True; + return False; +} + + +// execute a mouse binding +bool BInput::doAction(BlackboxWindow *window, unsigned int button, + unsigned int state, MouseEvent eventtype) const { + bool ret = False; + + assert(button == Button1 || button == Button2 || button == Button3 || + button == Button4 || button == Button5); + assert(eventtype >= 0 && eventtype < NUM_MOUSEEVENTS); + + MouseBindingList::const_iterator it = _mousebind.begin(); + const MouseBindingList::const_iterator end = _mousebind.end(); + for (; it != end; ++it) + if ((it->state == state || it->state == AnyModifier) && + it->button == button && it->event == eventtype && + it->action != NoAction) { + doAction(window, it->action); + ret = True; + } + return ret; +} + + +// determine if a mouse binding exists +bool BInput::hasAction(unsigned int button, unsigned int state, + MouseEvent eventtype) const { + assert(button == Button1 || button == Button2 || button == Button3 || + button == Button4 || button == Button5); + assert(eventtype >= 0 && eventtype < NUM_MOUSEEVENTS); + + MouseBindingList::const_iterator it = _mousebind.begin(); + const MouseBindingList::const_iterator end = _mousebind.end(); + for (; it != end; ++it) + if ((it->state == state || it->state == AnyModifier) && + it->button == button && it->event == eventtype && + it->action != NoAction) + return True; + return False; +} + + +void BInput::doAction(BlackboxWindow *window, Action action) const { + switch (action) { + case Raise: + if (window) window->raise(); + return; + + case Lower: + if (window) window->lower(); + return; + + case Shade: + if (window && ! window->isShaded()) window->shade(); + return; + + case Unshade: + if (window && window->isShaded()) window->shade(); + return; + + case ToggleShade: + if (window) window->shade(); + return; + + case Focus: + if (window && ! window->isFocused()) window->setInputFocus(); + return; + + case Iconify: + if (window && ! window->isIconic()) window->iconify(); + return; + + case ToggleMaximizeVert: + if (window) window->maximize(2); + return; + + case ToggleMaximizeHoriz: + if (window) window->maximize(3); + return; + + case ToggleMaximize: + if (window) window->maximize(1); + return; + + case Close: + if (window && window->isClosable()) window->close(); + return; + + case BeginMove: + if (window && window->isMovable()) { + Window root_return, child_return; + int root_x_return, root_y_return; + int win_x_return, win_y_return; + unsigned int mask_return; + + if (! XQueryPointer(_display, window->getClientWindow(), + &root_return, &child_return, + &root_x_return, &root_y_return, + &win_x_return, &win_y_return, + &mask_return)) + return; + window->beginMove(root_x_return, root_y_return); + } + return; + + case BeginResizeUL: + case BeginResizeUR: + case BeginResizeLL: + case BeginResizeLR: + case BeginResizeRelative: + if (window && window->isResizable()) { + Window root_return, child_return; + int root_x_return, root_y_return; + int win_x_return, win_y_return; + unsigned int mask_return; + + if (! XQueryPointer(_display, window->getClientWindow(), + &root_return, &child_return, + &root_x_return, &root_y_return, + &win_x_return, &win_y_return, + &mask_return)) + return; + + BlackboxWindow::Corner corner; + switch (action) { + case BeginResizeUL: corner = BlackboxWindow::TopLeft; break; + case BeginResizeUR: corner = BlackboxWindow::TopRight; break; + case BeginResizeLL: corner = BlackboxWindow::BottomLeft; break; + case BeginResizeLR: corner = BlackboxWindow::BottomRight; break; + case BeginResizeRelative: { + const Rect &r = window->frameRect(); + if (! r.contains(root_x_return, root_y_return)) + return; + + bool left = root_x_return < r.x() + (signed)(r.width() / 2); + bool top = root_y_return < r.y() + (signed)(r.height() / 2); + if (left) { + if (top) corner = BlackboxWindow::TopLeft; + else corner = BlackboxWindow::BottomLeft; + } else { + if (top) corner = BlackboxWindow::TopRight; + else corner = BlackboxWindow::BottomRight; + } + break; + } + default: assert(false); // unhandled action + } + window->beginResize(root_x_return, root_y_return, corner); + } + return; + + case ShowWindowMenu: + if (window) { + Window root_return, child_return; + int root_x_return, root_y_return; + int win_x_return, win_y_return; + unsigned int mask_return; + + if (! XQueryPointer(_display, window->getClientWindow(), + &root_return, &child_return, + &root_x_return, &root_y_return, + &win_x_return, &win_y_return, + &mask_return)) + return; + window->showWindowMenu(root_x_return, root_y_return); + } + return; + + default: + assert(false); // unhandled Action + } +} diff --git a/src/Input.hh b/src/Input.hh new file mode 100644 index 00000000..18f2cb8b --- /dev/null +++ b/src/Input.hh @@ -0,0 +1,153 @@ +// -*- mode: C++; indent-tabs-mode: nil; -*- +// Input.hh for Blackbox - an X11 Window manager +// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry +// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#ifndef __Input_hh +#define __Input_hh + +extern "C" { +#include +#include +} + +#include + +class Blackbox; +class BlackboxWindow; + +class BInput { +public: + enum MouseEvent { + InvalidEvent = -1, + + IconifyButtonClick, + MaximizeButtonClick, + CloseButtonClick, + + WindowFramePress, + WindowTitlePress, + WindowTitleDoublePress, + WindowClientPress, + RootWindowPress, + + WindowDrag, + WindowTitleDrag, + WindowHandleDrag, + WindowLeftGripDrag, + WindowRightGripDrag, + + NUM_MOUSEEVENTS + }; + + enum Action { + NoAction = 0, + Raise, + Lower, + Shade, + Unshade, + Focus, + Iconify, + ToggleMaximizeVert, + ToggleMaximizeHoriz, + ToggleMaximize, + ToggleShade, + Close, + BeginMove, + BeginResizeUL, + BeginResizeUR, + BeginResizeLL, + BeginResizeLR, + BeginResizeRelative, // picks a corner based on the mouse cursor's position + ShowWindowMenu, + NUM_ACTIONS + }; + + struct KeyBinding { + unsigned int button; + unsigned int state; + + // for keyboard events, this is applied to the focused window. + // for mouse events, this is applied to the window that was clicked on. + Action action; + + KeyBinding(unsigned int button, unsigned int state, Action action) { + assert(button > 0); + assert(action >= 0 && action < NUM_ACTIONS); + this->button = button; + this->state = state; + this->action = action; + } + }; + + struct MouseBinding : public KeyBinding { + MouseEvent event; + + MouseBinding(unsigned int button, unsigned int state, MouseEvent event, + Action action) : KeyBinding(button, state, action) { + assert(event >= 0 && event < NUM_MOUSEEVENTS); + this->event = event; + } + }; + + typedef std::list MouseBindingList; + typedef std::list KeyBindingList; + +private: + Blackbox *_blackbox; + Display *_display; + + MouseBindingList _mousebind; + KeyBindingList _keybind; + + void doAction(BlackboxWindow *window, Action action) const; + +public: + BInput(Blackbox *b); + virtual ~BInput(); + + void add(unsigned int button, unsigned int state, MouseEvent event, + Action action); + void remove(unsigned int button, unsigned int state, MouseEvent event, + Action action); + void add(unsigned int button, unsigned int state, Action action); + void remove(unsigned int button, unsigned int state, Action action); + + // execute a keyboard binding + // returns false if the specified binding doesnt exist + bool doAction(BlackboxWindow *window, unsigned int keycode, + unsigned int state) const; + // execute a mouse binding + // returns false if the specified binding doesnt exist + bool doAction(BlackboxWindow *window, unsigned int keycode, + unsigned int state, MouseEvent eventtype) const; + + // determine if a keyboard binding exists + bool hasAction(unsigned int keycode, unsigned int state) const; + // determine if a mouse binding exists + bool hasAction(unsigned int button, unsigned int state, + MouseEvent eventtype) const; + + const MouseBindingList &getMouseBindings(void) { return _mousebind; } + const KeyBindingList &getKeyBindings(void) { return _keybind; } +}; + +#endif // __Input_hh diff --git a/src/Makefile.am b/src/Makefile.am index 07e9287e..2a82a60a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,7 @@ CPPFLAGS=@CPPFLAGS@ @DEBUG@ \ bin_PROGRAMS= openbox -openbox_SOURCES= BaseDisplay.cc Basemenu.cc Clientmenu.cc Color.cc Configmenu.cc Configuration.cc GCCache.cc Iconmenu.cc Image.cc ImageControl.cc Netizen.cc Rootmenu.cc Screen.cc Slit.cc Texture.cc Timer.cc Toolbar.cc Util.cc Window.cc Windowmenu.cc Workspace.cc Workspacemenu.cc XAtom.cc blackbox.cc i18n.cc main.cc +openbox_SOURCES= BaseDisplay.cc Basemenu.cc Clientmenu.cc Color.cc Configmenu.cc Configuration.cc GCCache.cc Iconmenu.cc Image.cc ImageControl.cc Input.cc Netizen.cc Rootmenu.cc Screen.cc Slit.cc Texture.cc Timer.cc Toolbar.cc Util.cc Window.cc Windowmenu.cc Workspace.cc Workspacemenu.cc XAtom.cc blackbox.cc i18n.cc main.cc MAINTAINERCLEANFILES= Makefile.in @@ -40,95 +40,96 @@ distclean-local: BaseDisplay.o: BaseDisplay.cc i18n.hh ../nls/blackbox-nls.hh \ BaseDisplay.hh Timer.hh Util.hh GCCache.hh Color.hh Basemenu.o: Basemenu.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Basemenu.hh \ + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Basemenu.hh \ GCCache.hh Color.hh Image.hh Screen.hh Texture.hh Configmenu.hh \ Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh Clientmenu.o: Clientmenu.cc blackbox.hh i18n.hh ../nls/blackbox-nls.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ - Clientmenu.hh Basemenu.hh Screen.hh Color.hh Texture.hh Image.hh \ - Configmenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh \ - Workspacemenu.hh Window.hh Windowmenu.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Clientmenu.hh \ + Basemenu.hh Screen.hh Color.hh Texture.hh Image.hh Configmenu.hh \ + Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ + Window.hh Windowmenu.hh Color.o: Color.cc Color.hh BaseDisplay.hh Timer.hh Util.hh Configmenu.o: Configmenu.cc i18n.hh ../nls/blackbox-nls.hh \ Configmenu.hh Basemenu.hh Image.hh Timer.hh BaseDisplay.hh Util.hh \ Color.hh Toolbar.hh Screen.hh Texture.hh Iconmenu.hh Netizen.hh \ Rootmenu.hh Workspace.hh Workspacemenu.hh blackbox.hh \ - Configuration.hh XAtom.hh Window.hh Windowmenu.hh + Configuration.hh Window.hh Windowmenu.hh Configuration.o: Configuration.cc ../config.h Configuration.hh Util.hh GCCache.o: GCCache.cc GCCache.hh BaseDisplay.hh Timer.hh Util.hh \ Color.hh Iconmenu.o: Iconmenu.cc i18n.hh ../nls/blackbox-nls.hh Iconmenu.hh \ Basemenu.hh Screen.hh Color.hh Texture.hh Util.hh Image.hh Timer.hh \ BaseDisplay.hh Configmenu.hh Netizen.hh Rootmenu.hh Workspace.hh \ - Workspacemenu.hh blackbox.hh Configuration.hh XAtom.hh Window.hh \ - Windowmenu.hh + Workspacemenu.hh blackbox.hh Configuration.hh Window.hh Windowmenu.hh Image.o: Image.cc blackbox.hh i18n.hh ../nls/blackbox-nls.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh GCCache.hh \ - Color.hh Image.hh Texture.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh GCCache.hh Color.hh \ + Image.hh Texture.hh ImageControl.o: ImageControl.cc blackbox.hh i18n.hh \ ../nls/blackbox-nls.hh BaseDisplay.hh Timer.hh Util.hh \ - Configuration.hh XAtom.hh Color.hh Image.hh Texture.hh + Configuration.hh Color.hh Image.hh Texture.hh +Input.o: Input.cc Input.hh blackbox.hh i18n.hh ../nls/blackbox-nls.hh \ + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Window.hh \ + Windowmenu.hh Basemenu.hh Workspace.hh Screen.hh Color.hh Texture.hh \ + Image.hh Configmenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh \ + Workspacemenu.hh Netizen.o: Netizen.cc Netizen.hh Screen.hh Color.hh Texture.hh Util.hh \ Image.hh Timer.hh BaseDisplay.hh Configmenu.hh Basemenu.hh \ Iconmenu.hh Rootmenu.hh Workspace.hh Workspacemenu.hh blackbox.hh \ i18n.hh ../nls/blackbox-nls.hh Configuration.hh XAtom.hh Rootmenu.o: Rootmenu.cc blackbox.hh i18n.hh ../nls/blackbox-nls.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Rootmenu.hh \ + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Rootmenu.hh \ Basemenu.hh Screen.hh Color.hh Texture.hh Image.hh Configmenu.hh \ Iconmenu.hh Netizen.hh Workspace.hh Workspacemenu.hh Screen.o: Screen.cc ../config.h i18n.hh ../nls/blackbox-nls.hh \ - blackbox.hh BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ + blackbox.hh BaseDisplay.hh Timer.hh Util.hh Configuration.hh \ Clientmenu.hh Basemenu.hh GCCache.hh Color.hh Iconmenu.hh Image.hh \ Screen.hh Texture.hh Configmenu.hh Netizen.hh Rootmenu.hh \ Workspace.hh Workspacemenu.hh Slit.hh Toolbar.hh Window.hh \ - Windowmenu.hh + Windowmenu.hh XAtom.hh Input.hh Slit.o: Slit.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Image.hh \ - Color.hh Screen.hh Texture.hh Configmenu.hh Basemenu.hh Iconmenu.hh \ - Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh Slit.hh \ - Toolbar.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Image.hh Color.hh \ + Screen.hh Texture.hh Configmenu.hh Basemenu.hh Iconmenu.hh Netizen.hh \ + Rootmenu.hh Workspace.hh Workspacemenu.hh Slit.hh Toolbar.hh Texture.o: Texture.cc Texture.hh Color.hh Util.hh BaseDisplay.hh \ Timer.hh Image.hh Screen.hh Configmenu.hh Basemenu.hh Iconmenu.hh \ Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh blackbox.hh \ - i18n.hh ../nls/blackbox-nls.hh Configuration.hh XAtom.hh + i18n.hh ../nls/blackbox-nls.hh Configuration.hh Timer.o: Timer.cc BaseDisplay.hh Timer.hh Util.hh Toolbar.o: Toolbar.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ - Clientmenu.hh Basemenu.hh GCCache.hh Color.hh Iconmenu.hh Image.hh \ - Rootmenu.hh Screen.hh Texture.hh Configmenu.hh Netizen.hh \ - Workspace.hh Workspacemenu.hh Toolbar.hh Window.hh Windowmenu.hh \ - Slit.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Clientmenu.hh \ + Basemenu.hh GCCache.hh Color.hh Iconmenu.hh Image.hh Rootmenu.hh \ + Screen.hh Texture.hh Configmenu.hh Netizen.hh Workspace.hh \ + Workspacemenu.hh Toolbar.hh Window.hh Windowmenu.hh Slit.hh Util.o: Util.cc Util.hh Window.o: Window.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh GCCache.hh \ - Color.hh Iconmenu.hh Basemenu.hh Image.hh Screen.hh Texture.hh \ - Configmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ - Toolbar.hh Window.hh Windowmenu.hh Slit.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh GCCache.hh Color.hh \ + Iconmenu.hh Basemenu.hh Image.hh Screen.hh Texture.hh Configmenu.hh \ + Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh Toolbar.hh \ + Window.hh Windowmenu.hh Slit.hh XAtom.hh Input.hh Windowmenu.o: Windowmenu.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Screen.hh \ - Color.hh Texture.hh Image.hh Configmenu.hh Basemenu.hh Iconmenu.hh \ - Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh Window.hh \ - Windowmenu.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Screen.hh Color.hh \ + Texture.hh Image.hh Configmenu.hh Basemenu.hh Iconmenu.hh Netizen.hh \ + Rootmenu.hh Workspace.hh Workspacemenu.hh Window.hh Windowmenu.hh Workspace.o: Workspace.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ - Clientmenu.hh Basemenu.hh Netizen.hh Screen.hh Color.hh Texture.hh \ - Image.hh Configmenu.hh Iconmenu.hh Rootmenu.hh Workspace.hh \ - Workspacemenu.hh Toolbar.hh Window.hh Windowmenu.hh + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Clientmenu.hh \ + Basemenu.hh Netizen.hh Screen.hh Color.hh Texture.hh Image.hh \ + Configmenu.hh Iconmenu.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ + Toolbar.hh Window.hh Windowmenu.hh XAtom.hh Workspacemenu.o: Workspacemenu.cc i18n.hh ../nls/blackbox-nls.hh \ - blackbox.hh BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh \ + blackbox.hh BaseDisplay.hh Timer.hh Util.hh Configuration.hh \ Screen.hh Color.hh Texture.hh Image.hh Configmenu.hh Basemenu.hh \ Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ Toolbar.hh -XAtom.o: XAtom.cc ../config.h XAtom.hh blackbox.hh i18n.hh \ - ../nls/blackbox-nls.hh BaseDisplay.hh Timer.hh Util.hh \ - Configuration.hh Screen.hh Color.hh Texture.hh Image.hh Configmenu.hh \ - Basemenu.hh Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh \ - Workspacemenu.hh +XAtom.o: XAtom.cc ../config.h XAtom.hh Screen.hh Color.hh Texture.hh \ + Util.hh Image.hh Timer.hh BaseDisplay.hh Configmenu.hh Basemenu.hh \ + Iconmenu.hh Netizen.hh Rootmenu.hh Workspace.hh Workspacemenu.hh \ + blackbox.hh i18n.hh ../nls/blackbox-nls.hh Configuration.hh blackbox.o: blackbox.cc i18n.hh ../nls/blackbox-nls.hh blackbox.hh \ - BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh Basemenu.hh \ + BaseDisplay.hh Timer.hh Util.hh Configuration.hh Basemenu.hh \ Clientmenu.hh GCCache.hh Color.hh Image.hh Rootmenu.hh Screen.hh \ Texture.hh Configmenu.hh Iconmenu.hh Netizen.hh Workspace.hh \ - Workspacemenu.hh Slit.hh Toolbar.hh Window.hh Windowmenu.hh + Workspacemenu.hh Slit.hh Toolbar.hh Window.hh Windowmenu.hh XAtom.hh \ + Input.hh i18n.o: i18n.cc i18n.hh ../nls/blackbox-nls.hh main.o: main.cc ../version.h i18n.hh ../nls/blackbox-nls.hh \ - blackbox.hh BaseDisplay.hh Timer.hh Util.hh Configuration.hh XAtom.hh + blackbox.hh BaseDisplay.hh Timer.hh Util.hh Configuration.hh diff --git a/src/Screen.cc b/src/Screen.cc index 73dfeaf1..88cba673 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -88,6 +88,7 @@ using std::string; #include "Workspace.hh" #include "Workspacemenu.hh" #include "XAtom.hh" +#include "Input.hh" #ifndef FONT_ELEMENT_SIZE #define FONT_ELEMENT_SIZE 50 @@ -313,6 +314,7 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(bb, scrn) { // call this again just in case a window we found updates the Strut list updateAvailableArea(); + updateFocusModel(); } @@ -2170,9 +2172,10 @@ void BScreen::toggleFocusModel(FocusModel model) { if (model == SloppyFocus) { saveSloppyFocus(True); } else { + // we're cheating here to save writing the config file 3 times + resource.auto_raise = False; + resource.click_raise = False; saveSloppyFocus(False); - saveAutoRaise(False); - saveClickRaise(False); } updateFocusModel(); @@ -2181,8 +2184,31 @@ void BScreen::toggleFocusModel(FocusModel model) { void BScreen::updateFocusModel() { - std::for_each(workspacesList.begin(), workspacesList.end(), - std::mem_fun(&Workspace::updateFocusModel)); + std::for_each(iconList.begin(), iconList.end(), + std::mem_fun(&BlackboxWindow::ungrabButtons)); + std::for_each(windowList.begin(), windowList.end(), + std::mem_fun(&BlackboxWindow::ungrabButtons)); + + if (! resource.sloppy_focus) { + blackbox->getInput()->add(Button1, 0, BInput::WindowClientPress, + BInput::Raise); + blackbox->getInput()->add(Button1, 0, BInput::WindowClientPress, + BInput::Focus); + } else { + if (resource.click_raise) + blackbox->getInput()->add(Button1, 0, BInput::WindowClientPress, + BInput::Raise); + else + blackbox->getInput()->remove(Button1, 0, BInput::WindowClientPress, + BInput::Raise); + blackbox->getInput()->remove(Button1, 0, BInput::WindowClientPress, + BInput::Focus); + } + + std::for_each(iconList.begin(), iconList.end(), + std::mem_fun(&BlackboxWindow::grabButtons)); + std::for_each(windowList.begin(), windowList.end(), + std::mem_fun(&BlackboxWindow::grabButtons)); } diff --git a/src/Util.cc b/src/Util.cc index bc685bfa..9dadb3e1 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -141,6 +141,12 @@ bool Rect::intersects(const Rect &a) const { } +bool Rect::contains(int __x, int __y) const { + return __x >= _x1 && __x <= _x2 && + __y >= _y1 && __y <= _y2; +} + + string expandTilde(const string& s) { if (s[0] != '~') return s; diff --git a/src/Util.hh b/src/Util.hh index 2a40308d..393c0089 100644 --- a/src/Util.hh +++ b/src/Util.hh @@ -71,6 +71,7 @@ public: inline bool valid(void) const { return _x2 > _x1 && _y2 > _y1; } bool intersects(const Rect &a) const; + bool contains(int _x, int _y) const; private: int _x1, _y1, _x2, _y2; diff --git a/src/Window.cc b/src/Window.cc index 7c5b823b..4bfca5c5 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -54,6 +54,8 @@ extern "C" { #include "Windowmenu.hh" #include "Workspace.hh" #include "Slit.hh" +#include "XAtom.hh" +#include "Input.hh" using std::string; @@ -78,6 +80,7 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { client.window = w; screen = s; xatom = blackbox->getXAtom(); + input = blackbox->getInput(); if (! validateClient()) { delete this; @@ -271,25 +274,7 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) { } #endif // SHAPE - if ((! screen->isSloppyFocus()) || screen->doClickRaise()) { - // grab button 1 for changing focus/raising - blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask, - GrabModeSync, GrabModeSync, None, None); - } - - if (functions & Func_Move) - blackbox->grabButton(Button1, Mod1Mask, frame.window, True, - ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, - GrabModeAsync, frame.window, - blackbox->getMoveCursor()); - blackbox->grabButton(Button2, Mod1Mask, frame.window, True, - ButtonReleaseMask, GrabModeAsync, GrabModeAsync, - None, None); - if (functions & Func_Resize) - blackbox->grabButton(Button3, Mod1Mask, frame.window, True, - ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, - GrabModeAsync, None, - blackbox->getLowerRightAngleCursor()); + grabButtons(); positionWindows(); decorate(); @@ -857,17 +842,6 @@ void BlackboxWindow::reconfigure(void) { } -void BlackboxWindow::updateFocusModel(void) { - if ((! screen->isSloppyFocus()) || screen->doClickRaise()) { - // grab button 1 for changing focus/raising - blackbox->grabButton(Button1, 0, frame.plate, True, ButtonPressMask, - GrabModeSync, GrabModeSync, None, None); - } else { - blackbox->ungrabButton(Button1, 0, frame.plate); - } -} - - void BlackboxWindow::positionWindows(void) { XMoveResizeWindow(blackbox->getXDisplay(), frame.window, frame.rect.x(), frame.rect.y(), frame.inside_w, @@ -1651,7 +1625,7 @@ void BlackboxWindow::show(void) { } -void BlackboxWindow::deiconify(bool reassoc, bool raise) { +void BlackboxWindow::deiconify(bool reassoc, bool doraise) { if (flags.iconic || reassoc) screen->reassociateWindow(this, BSENTINEL, False); else if (blackbox_attrib.workspace != screen->getCurrentWorkspace()->getID()) @@ -1667,8 +1641,18 @@ void BlackboxWindow::deiconify(bool reassoc, bool raise) { } } - if (raise) - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); + if (doraise) + raise(); +} + + +void BlackboxWindow::raise(void) { + screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); +} + + +void BlackboxWindow::lower(void) { + screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this); } @@ -1791,7 +1775,7 @@ void BlackboxWindow::maximize(unsigned int button) { configure(frame.changing.x(), frame.changing.y(), frame.changing.width(), frame.changing.height()); if (flags.focused) - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); + raise(); redrawAllButtons(); setState(current_state); } @@ -2393,7 +2377,7 @@ void BlackboxWindow::redrawCloseButton(bool pressed) { } -void BlackboxWindow::mapRequestEvent(XMapRequestEvent *re) { +void BlackboxWindow::mapRequestEvent(const XMapRequestEvent *re) { if (re->window != client.window) return; @@ -2416,7 +2400,7 @@ void BlackboxWindow::mapRequestEvent(XMapRequestEvent *re) { case ZoomState: default: show(); - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); + raise(); if (! blackbox->isStartup() && (isTransient() || screen->doFocusNew())) { XSync(blackbox->getXDisplay(), False); // make sure the frame is mapped.. setInputFocus(); @@ -2426,7 +2410,7 @@ void BlackboxWindow::mapRequestEvent(XMapRequestEvent *re) { } -void BlackboxWindow::unmapNotifyEvent(XUnmapEvent *ue) { +void BlackboxWindow::unmapNotifyEvent(const XUnmapEvent *ue) { if (ue->window != client.window) return; @@ -2439,7 +2423,7 @@ void BlackboxWindow::unmapNotifyEvent(XUnmapEvent *ue) { } -void BlackboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) { +void BlackboxWindow::destroyNotifyEvent(const XDestroyWindowEvent *de) { if (de->window != client.window) return; @@ -2452,7 +2436,7 @@ void BlackboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) { } -void BlackboxWindow::reparentNotifyEvent(XReparentEvent *re) { +void BlackboxWindow::reparentNotifyEvent(const XReparentEvent *re) { if (re->window != client.window || re->parent == frame.plate) return; @@ -2556,7 +2540,7 @@ void BlackboxWindow::propertyNotifyEvent(Atom atom) { } -void BlackboxWindow::exposeEvent(XExposeEvent *ee) { +void BlackboxWindow::exposeEvent(const XExposeEvent *ee) { if (frame.label == ee->window && (decorations & Decor_Titlebar)) redrawLabel(); else if (frame.close_button == ee->window) @@ -2568,7 +2552,7 @@ void BlackboxWindow::exposeEvent(XExposeEvent *ee) { } -void BlackboxWindow::configureRequestEvent(XConfigureRequestEvent *cr) { +void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) { if (cr->window != client.window || flags.iconic) return; @@ -2597,147 +2581,226 @@ void BlackboxWindow::configureRequestEvent(XConfigureRequestEvent *cr) { switch (cr->detail) { case Below: case BottomIf: - screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this); + lower(); break; case Above: case TopIf: default: - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); + raise(); break; } } } -void BlackboxWindow::buttonPressEvent(XButtonEvent *be) { - if (frame.maximize_button == be->window) { - redrawMaximizeButton(True); - } else if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) { - if (! flags.focused) - setInputFocus(); - - if (frame.iconify_button == be->window) { - redrawIconifyButton(True); - } else if (frame.close_button == be->window) { - redrawCloseButton(True); - } else if (frame.plate == be->window) { - if (windowmenu && windowmenu->isVisible()) windowmenu->hide(); - - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); - - XAllowEvents(blackbox->getXDisplay(), ReplayPointer, be->time); - } else { - if (frame.title == be->window || frame.label == be->window) { - if (((be->time - lastButtonPressTime) <= - blackbox->getDoubleClickInterval()) || - (be->state & ControlMask)) { - lastButtonPressTime = 0; - shade(); - } else { - lastButtonPressTime = be->time; - } +void BlackboxWindow::grabButtons(void) { + const BInput::MouseBindingList &mbindings = input->getMouseBindings(); + + BInput::MouseBindingList::const_iterator mit = mbindings.begin(); + const BInput::MouseBindingList::const_iterator mend = mbindings.end(); + for (; mit != mend; ++mit) { + // dont grab for an action the window can't perform + //if (! (mit->action == BInput::BeginMove && functions & Func_Move) && + // ! (mit->action == BInput::BeginResize && functions & Func_Resize)) { + switch (mit->event) { + case BInput::WindowClientPress: + blackbox->grabButton(mit->button, mit->state, frame.plate, True, + ButtonPressMask, GrabModeSync, GrabModeSync, + frame.plate, None); + break; + case BInput::WindowDrag: + blackbox->grabButton(mit->button, mit->state, frame.window, True, + ButtonMotionMask, GrabModeAsync, GrabModeAsync, + frame.window, None); + default: + break; } + } +} - if (windowmenu && windowmenu->isVisible()) windowmenu->hide(); - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); +void BlackboxWindow::ungrabButtons(void) { + const BInput::MouseBindingList &mbindings = input->getMouseBindings(); + + BInput::MouseBindingList::const_iterator mit = mbindings.begin(); + const BInput::MouseBindingList::const_iterator mend = mbindings.end(); + for (; mit != mend; ++mit) { + switch (mit->event) { + case BInput::WindowClientPress: + blackbox->ungrabButton(mit->button, mit->state, frame.plate); + break; + case BInput::WindowDrag: + blackbox->ungrabButton(mit->button, mit->state, frame.window); + default: + break; } - } else if (be->button == 2 && (be->window != frame.iconify_button) && - (be->window != frame.close_button)) { - screen->getWorkspace(blackbox_attrib.workspace)->lowerWindow(this); - } else if (windowmenu && be->button == 3 && - (frame.title == be->window || frame.label == be->window || - frame.handle == be->window || frame.window == be->window)) { - int mx = 0, my = 0; - - if (frame.title == be->window || frame.label == be->window) { - mx = be->x_root - (windowmenu->getWidth() / 2); - my = frame.rect.y() + frame.title_h + frame.border_w; - } else if (frame.handle == be->window) { - mx = be->x_root - (windowmenu->getWidth() / 2); - my = frame.rect.bottom() - frame.handle_h - (frame.border_w * 3) - - windowmenu->getHeight(); - } else { - mx = be->x_root - (windowmenu->getWidth() / 2); + } +} - if (be->y <= static_cast(frame.bevel_w)) - my = frame.rect.y() + frame.title_h; - else - my = be->y_root - (windowmenu->getHeight() / 2); - } - // snap the window menu into a corner if necessary - we check the - // position of the menu with the coordinates of the client to - // make the comparisions easier. - // XXX: this needs some work! - if (mx > client.rect.right() - - static_cast(windowmenu->getWidth())) - mx = frame.rect.right() - windowmenu->getWidth() - frame.border_w + 1; - if (mx < client.rect.left()) - mx = frame.rect.x(); - - if (my > client.rect.bottom() - - static_cast(windowmenu->getHeight())) - my = frame.rect.bottom() - windowmenu->getHeight() - frame.border_w + 1; - if (my < client.rect.top()) - my = frame.rect.y() + ((decorations & Decor_Titlebar) ? - frame.title_h : 0); - - if (windowmenu) { - if (! windowmenu->isVisible()) { - windowmenu->move(mx, my); - windowmenu->show(); - XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID()); - XRaiseWindow(blackbox->getXDisplay(), - windowmenu->getSendToMenu()->getWindowID()); - } else { - windowmenu->hide(); - } +void BlackboxWindow::buttonPressEvent(const XButtonEvent *be) { + if (windowmenu && windowmenu->isVisible()) windowmenu->hide(); + + if (frame.maximize_button == be->window) { + if (input->hasAction(be->button, be->state, BInput::MaximizeButtonClick)) + redrawMaximizeButton(True); + } else if (frame.iconify_button == be->window) { + if (input->hasAction(be->button, be->state, BInput::IconifyButtonClick)) + redrawIconifyButton(True); + } else if (frame.close_button == be->window) { + if (input->hasAction(be->button, be->state, BInput::CloseButtonClick)) + redrawCloseButton(True); + } else if (frame.title == be->window || frame.label == be->window) { + if (be->time - lastButtonPressTime <= blackbox->getDoubleClickInterval()) { + lastButtonPressTime = 0; + input->doAction(this, be->button, be->state, + BInput::WindowTitleDoublePress); + } else { + lastButtonPressTime = be->time; + input->doAction(this, be->button, be->state, + BInput::WindowTitlePress); } - // mouse wheel up - } else if (be->button == 4) { - if ((be->window == frame.label || - be->window == frame.title) && - ! flags.shaded) - shade(); - // mouse wheel down - } else if (be->button == 5) { - if ((be->window == frame.label || - be->window == frame.title) && - flags.shaded) - shade(); + } else if (frame.plate == be->window) { + input->doAction(this, be->button, be->state, BInput::WindowClientPress); + // buttons on the client window are grabbed in Sync mode, so we need to let + // events back through again + XAllowEvents(blackbox->getXDisplay(), ReplayPointer, be->time); + } else if (frame.window == be->window || frame.handle == be->window) { + input->doAction(this, be->button, be->state, BInput::WindowFramePress); } } -void BlackboxWindow::buttonReleaseEvent(XButtonEvent *re) { - if (re->window == frame.maximize_button) { - if ((re->x >= 0 && re->x <= static_cast(frame.button_w)) && - (re->y >= 0 && re->y <= static_cast(frame.button_w))) { - maximize(re->button); - } else { +void BlackboxWindow::showWindowMenu(int root_x, int root_y) { + if (! windowmenu || windowmenu->isVisible()) + return; + + root_x -= windowmenu->getWidth() / 2; + root_y -= windowmenu->getHeight() / 2; + + // snap the window menu into a corner/side if necessary + int left_edge, right_edge, top_edge, bottom_edge; + + left_edge = frame.rect.x(); + right_edge = frame.rect.right() - windowmenu->getWidth() - frame.border_w - 1; + if (decorations & Decor_Titlebar) + top_edge = frame.rect.y() + frame.title_h + frame.border_w; + else + top_edge = frame.rect.y() + frame.border_w; + if (decorations & Decor_Handle) + bottom_edge = frame.rect.bottom() - frame.handle_h - (frame.border_w * 3) - + windowmenu->getHeight(); + else + bottom_edge = frame.rect.bottom() - windowmenu->getHeight() - + frame.border_w + 1; + + if (root_x > right_edge) + root_x = right_edge; + if (root_x < left_edge) + root_x = left_edge; + + if (root_y > bottom_edge) + root_y = bottom_edge; + if (root_y < top_edge) + root_y = top_edge; + + + windowmenu->move(root_x, root_y); + windowmenu->show(); + XRaiseWindow(blackbox->getXDisplay(), windowmenu->getWindowID()); + XRaiseWindow(blackbox->getXDisplay(), + windowmenu->getSendToMenu()->getWindowID()); +} + + +void BlackboxWindow::buttonReleaseEvent(const XButtonEvent *re) { + // get the proper state, without the button that was released + unsigned int state; + switch (re->button) { + case Button1: + state = re->state & ~Button1Mask; + break; + case Button2: + state = re->state & ~Button2Mask; + break; + case Button3: + state = re->state & ~Button3Mask; + break; + case Button4: + state = re->state & ~Button4Mask; + break; + case Button5: + state = re->state & ~Button5Mask; + break; + default: + assert(false); // unhandled button + } + + if (frame.maximize_button == re->window) { + if ((re->x < 0 || re->x >= static_cast(frame.button_w)) || + (re->y < 0 || re->y >= static_cast(frame.button_w)) || + ! input->doAction(this, re->button, state, + BInput::MaximizeButtonClick)) redrawMaximizeButton(flags.maximized); - } - } else if (re->window == frame.iconify_button) { - if ((re->x >= 0 && re->x <= static_cast(frame.button_w)) && - (re->y >= 0 && re->y <= static_cast(frame.button_w))) { - iconify(); - } else { + } else if (frame.iconify_button == re->window) { + if ((re->x < 0 || re->x >= static_cast(frame.button_w)) || + (re->y < 0 || re->y >= static_cast(frame.button_w)) || + ! input->doAction(this, re->button, state, + BInput::IconifyButtonClick)) redrawIconifyButton(False); - } - } else if (re->window == frame.close_button) { - if ((re->x >= 0 && re->x <= static_cast(frame.button_w)) && - (re->y >= 0 && re->y <= static_cast(frame.button_w))) - close(); - redrawCloseButton(False); + } else if (frame.close_button == re->window) { + if ((re->x < 0 || re->x >= static_cast(frame.button_w)) || + (re->y < 0 || re->y >= static_cast(frame.button_w))) + input->doAction(this, re->button, state, BInput::CloseButtonClick); + redrawCloseButton(False); } else if (flags.moving) { endMove(); } else if (flags.resizing) { endResize(); - } else if (re->window == frame.window) { - if (re->button == 2 && re->state == Mod1Mask) - XUngrabPointer(blackbox->getXDisplay(), CurrentTime); + } +} + + +void BlackboxWindow::motionNotifyEvent(const XMotionEvent *me) { + // get the button that is being used + // get the proper state, without the button that is being used + unsigned int button; + unsigned int state; + if (me->state & Button1Mask) { + button = Button1; + state = me->state & ~Button1Mask; + } else if (me->state & Button2Mask) { + button = Button2; + state = me->state & ~Button2Mask; + } else if (me->state & Button3Mask) { + button = Button3; + state = me->state & ~Button3Mask; + } else if (me->state & Button4Mask) { + button = Button4; + state = me->state & ~Button4Mask; + } else if (me->state & Button5Mask) { + button = Button5; + state = me->state & ~Button5Mask; + } else { + return; + } + + if (flags.moving) { + doMove(me->x_root, me->y_root); + } else if (flags.resizing) { + doResize(me->x_root, me->y_root); + } else { + if (frame.title == me->window || frame.label == me->window) + input->doAction(this, button, state, BInput::WindowTitleDrag); + else if (frame.handle == me->window) + input->doAction(this, button, state, BInput::WindowHandleDrag); + else if (frame.left_grip == me->window) + input->doAction(this, button, state, BInput::WindowLeftGripDrag); + else if (frame.right_grip == me->window) + input->doAction(this, button, state, BInput::WindowRightGripDrag); + else if (frame.window == me->window) + input->doAction(this, button, state, BInput::WindowDrag); } } @@ -3132,30 +3195,6 @@ void BlackboxWindow::endResize(void) { } -void BlackboxWindow::motionNotifyEvent(XMotionEvent *me) { - if (flags.moving) { - doMove(me->x_root, me->y_root); - } else if (flags.resizing) { - doResize(me->x_root, me->y_root); - } else { - if (! flags.resizing && (me->state & Button1Mask) && - (functions & Func_Move) && - (frame.title == me->window || frame.label == me->window || - frame.handle == me->window || frame.window == me->window)) { - beginMove(me->x_root, me->y_root); - } else if ((functions & Func_Resize) && - (((me->state & Button1Mask) && - (me->window == frame.right_grip || - me->window == frame.left_grip)) || - (me->state & (Mod1Mask | Button3Mask) && - me->window == frame.window))) { - beginResize(me->x_root, me->y_root, - (me->window == frame.left_grip) ? BottomLeft : BottomRight); - } - } -} - - #ifdef SHAPE void BlackboxWindow::shapeEvent(XShapeEvent *) { if (blackbox->hasShapeExtensions() && flags.shaped) { @@ -3212,7 +3251,7 @@ void BlackboxWindow::restore(bool remap) { // timer for autoraise void BlackboxWindow::timeout(void) { - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); + raise(); } @@ -3255,7 +3294,7 @@ void BlackboxWindow::changeBlackboxHints(BlackboxHints *net) { withdraw(); } else { show(); - screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this); + raise(); } } diff --git a/src/Window.hh b/src/Window.hh index aab1a412..ea5c0d73 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -38,6 +38,11 @@ extern "C" { #include "Timer.hh" #include "Util.hh" #include "Windowmenu.hh" +#include "Workspace.hh" +#include "Screen.hh" + +class XAtom; +class BInput; #define MwmHintsFunctions (1l << 0) #define MwmHintsDecorations (1l << 1) @@ -126,6 +131,7 @@ private: Blackbox *blackbox; BScreen *screen; XAtom *xatom; + BInput *input; BTimer *timer; BlackboxAttributes blackbox_attrib; @@ -317,6 +323,7 @@ public: inline bool isIconifiable(void) const { return functions & Func_Iconify; } inline bool isMaximizable(void) const { return functions & Func_Maximize; } inline bool isResizable(void) const { return functions & Func_Resize; } + inline bool isMovable(void) const { return functions & Func_Move; } inline bool isClosable(void) const { return functions & Func_Close; } inline bool isDesktop(void) const { return window_type == Type_Desktop; } @@ -371,14 +378,18 @@ public: void iconify(void); void deiconify(bool reassoc = True, bool raise = True); void show(void); + void showWindowMenu(int root_x, int root_y); void close(void); void withdraw(void); void maximize(unsigned int button); void remaximize(void); void shade(void); void stick(void); + void raise(void); + void lower(void); void reconfigure(void); - void updateFocusModel(void); + void grabButtons(void); + void ungrabButtons(void); void installColormap(bool install); void restore(bool remap); void configure(int dx, int dy, unsigned int dw, unsigned int dh); @@ -386,16 +397,16 @@ public: void changeBlackboxHints(BlackboxHints *net); void restoreAttributes(void); - void buttonPressEvent(XButtonEvent *be); - void buttonReleaseEvent(XButtonEvent *re); - void motionNotifyEvent(XMotionEvent *me); - void destroyNotifyEvent(XDestroyWindowEvent */*unused*/); - void mapRequestEvent(XMapRequestEvent *mre); - void unmapNotifyEvent(XUnmapEvent */*unused*/); - void reparentNotifyEvent(XReparentEvent */*unused*/); + void buttonPressEvent(const XButtonEvent *be); + void buttonReleaseEvent(const XButtonEvent *re); + void motionNotifyEvent(const XMotionEvent *me); + void destroyNotifyEvent(const XDestroyWindowEvent */*unused*/); + void mapRequestEvent(const XMapRequestEvent *mre); + void unmapNotifyEvent(const XUnmapEvent */*unused*/); + void reparentNotifyEvent(const XReparentEvent */*unused*/); void propertyNotifyEvent(Atom atom); - void exposeEvent(XExposeEvent *ee); - void configureRequestEvent(XConfigureRequestEvent *cr); + void exposeEvent(const XExposeEvent *ee); + void configureRequestEvent(const XConfigureRequestEvent *cr); #ifdef SHAPE void configureShape(void); diff --git a/src/Workspace.cc b/src/Workspace.cc index 60efba1e..2aaf80ee 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -320,12 +320,6 @@ void Workspace::reconfigure(void) { } -void Workspace::updateFocusModel(void) { - std::for_each(windowList.begin(), windowList.end(), - std::mem_fun(&BlackboxWindow::updateFocusModel)); -} - - BlackboxWindow *Workspace::getWindow(unsigned int index) { if (index < windowList.size()) { BlackboxWindowList::iterator it = windowList.begin(); diff --git a/src/Workspace.hh b/src/Workspace.hh index 31ddace8..0059e293 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -102,7 +102,6 @@ public: void raiseWindow(BlackboxWindow *w); void lowerWindow(BlackboxWindow *w); void reconfigure(void); - void updateFocusModel(void); void setCurrent(void); void setName(const std::string& new_name); }; diff --git a/src/blackbox.cc b/src/blackbox.cc index 3cc12bc4..36828f7e 100644 --- a/src/blackbox.cc +++ b/src/blackbox.cc @@ -111,6 +111,7 @@ using std::string; #include "Workspace.hh" #include "Workspacemenu.hh" #include "XAtom.hh" +#include "Input.hh" // X event scanner for enter/leave notifies - adapted from twm struct scanargs { @@ -162,6 +163,7 @@ Blackbox::Blackbox(char **m_argv, char *dpy_name, char *rc, char *menu) load_rc(); xatom = new XAtom(getXDisplay()); + input = new BInput(this); cursor.session = XCreateFontCursor(getXDisplay(), XC_left_ptr); cursor.move = XCreateFontCursor(getXDisplay(), XC_fleur); diff --git a/src/blackbox.hh b/src/blackbox.hh index a5f55491..a5bb8157 100644 --- a/src/blackbox.hh +++ b/src/blackbox.hh @@ -51,7 +51,6 @@ extern "C" { #include "BaseDisplay.hh" #include "Configuration.hh" #include "Timer.hh" -#include "XAtom.hh" #define AttribShaded (1l << 0) #define AttribMaxHoriz (1l << 1) @@ -92,6 +91,8 @@ class BWindowGroup; class Basemenu; class Toolbar; class Slit; +class XAtom; +class BInput; extern I18n i18n; @@ -152,6 +153,7 @@ private: BTimer *timer; Configuration config; XAtom *xatom; + BInput *input; bool no_focus, reconfigure_wait, reread_menu_wait; Time last_time; @@ -198,6 +200,7 @@ public: void removeSlitSearch(Window window); inline XAtom *getXAtom(void) { return xatom; } + inline BInput *getInput(void) { return input; } inline BlackboxWindow *getFocusedWindow(void) { return focused_window; } inline BlackboxWindow *getChangingWindow(void) { return changing_window; }