]> Dogcows Code - chaz/openbox/commitdiff
Configureable button mappings!
authorDana Jansens <danakj@orodu.net>
Sat, 29 Jun 2002 23:50:04 +0000 (23:50 +0000)
committerDana Jansens <danakj@orodu.net>
Sat, 29 Jun 2002 23:50:04 +0000 (23:50 +0000)
12 files changed:
src/Input.cc [new file with mode: 0644]
src/Input.hh [new file with mode: 0644]
src/Makefile.am
src/Screen.cc
src/Util.cc
src/Util.hh
src/Window.cc
src/Window.hh
src/Workspace.cc
src/Workspace.hh
src/blackbox.cc
src/blackbox.hh

diff --git a/src/Input.cc b/src/Input.cc
new file mode 100644 (file)
index 0000000..0c243ec
--- /dev/null
@@ -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 <shaleh@debian.org>
+// 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 (file)
index 0000000..18f2cb8
--- /dev/null
@@ -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 <shaleh@debian.org>
+// 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 <X11/Xlib.h>
+#include <X11/Xutil.h>
+}
+
+#include <list>
+
+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<MouseBinding> MouseBindingList;
+  typedef std::list<KeyBinding> 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
index 07e9287e5577c8bf6b10ee07ec69826319dbc744..2a82a60a421e6e7d40517df8cd4eea8dea7b8a5c 100644 (file)
@@ -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
index 73dfeaf1bd71d91d4adac0490657c83e7fe5cd85..88cba6733fbc24e2df1fabfc56c6e2294dbf7ff7 100644 (file)
@@ -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));
 }
 
 
index bc685bfaf4dac4e2c55cd7c133ed83933c62cd36..9dadb3e10ea510fcd73961536fdc7f8958d83a3b 100644 (file)
@@ -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;
 
index 2a40308d8c34ad84e44ca4d39b071df82ea16024..393c00893beca853fcc7b10189029090ab48a454 100644 (file)
@@ -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;
index 7c5b823bc2df3587cf0ac0bee9500d2636590b60..4bfca5c5f68ea76ae7b7485232d2e25f927ee303 100644 (file)
@@ -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<signed>(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<signed>(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<signed>(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<signed>(frame.button_w)) &&
-        (re->y >= 0 && re->y <= static_cast<signed>(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<signed>(frame.button_w)) ||
+        (re->y < 0 || re->y >= static_cast<signed>(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<signed>(frame.button_w)) &&
-        (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w))) {
-      iconify();
-    } else {
+  } else if (frame.iconify_button == re->window) {
+    if ((re->x < 0 || re->x >= static_cast<signed>(frame.button_w)) ||
+        (re->y < 0 || re->y >= static_cast<signed>(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<signed>(frame.button_w)) &&
-        (re->y >= 0 && re->y <= static_cast<signed>(frame.button_w)))
-      close();
-    redrawCloseButton(False);
+  } else if (frame.close_button == re->window) {
+    if ((re->x < 0 || re->x >= static_cast<signed>(frame.button_w)) ||
+        (re->y < 0 || re->y >= static_cast<signed>(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();
     }
   }
 
index aab1a412778d049e1ea9d7296316d6c42ff939ce..ea5c0d733c07f41a68655a1827b24faa2783ba92 100644 (file)
@@ -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);
index 60efba1e3845badb92d84e937b1b09f8346ce3ac..2aaf80eeb35f9a54b0b0260a47e97abe1909557a 100644 (file)
@@ -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();
index 31ddace817c49dbe2dd991172b1cfe72ae1fa41d..0059e293fdcd4c46d59b7e94a2b5f0dbda7be1dd 100644 (file)
@@ -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);
 };
index 3cc12bc4523e65333d00e6ab719efd728d7b2114..36828f7e5e3ce2927e24bebe5521c2a3731a0a49 100644 (file)
@@ -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);
index a5f5549153a2e084be618a9cbbd4c62572019baf..a5bb815787336c15fea243fa36bb9b477d0c17c6 100644 (file)
@@ -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; }
This page took 0.057523 seconds and 4 git commands to generate.