Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

ob::Actions Class Reference

#include <actions.hh>

Inheritance diagram for ob::Actions:

Inheritance graph
[legend]
Collaboration diagram for ob::Actions:

Collaboration graph
[legend]
List of all members.

Detailed Description

The action interface for user-available actions.

When these actions are fired, hooks to the guile engine are fired so that guile code is run.

Definition at line 28 of file actions.hh.

Public Methods

 Actions ()
 Constructs an Actions object.

virtual ~Actions ()
 Destroys the Actions object.

virtual void buttonPressHandler (const XButtonEvent &e)
 Called whenever a button of the pointer is pressed.

virtual void buttonReleaseHandler (const XButtonEvent &e)
 Called whenever a button of the pointer is released.

virtual void enterHandler (const XCrossingEvent &e)
 Called whenever the pointer enters a window.

virtual void leaveHandler (const XCrossingEvent &e)
 Called whenever the pointer leaves a window.

virtual void keyPressHandler (const XKeyEvent &e)
 Called whenever any key is pressed.

virtual void keyReleaseHandler (const XKeyEvent &e)
 Called whenever any key is released.

virtual void motionHandler (const XMotionEvent &e)
 Called whenever the pointer moved.


Private Methods

void insertPress (const XButtonEvent &e)
void removePress (const XButtonEvent &e)

Private Attributes

unsigned int _button
 The mouse button currently being watched from a press for a CLICK.

ButtonReleaseAction _release
 The last button release processed for CLICKs.

ButtonPressAction_posqueue [BUTTONS]
 The point where the mouse was when each mouse button was pressed.

bool _dragging
 This is set to true once a drag has started and false when done to make sure the threshold isnt checked anymore once a drag is underway.


Static Private Attributes

const int BUTTONS = 5


Constructor & Destructor Documentation

ob::Actions::Actions  
 

Constructs an Actions object.

Definition at line 23 of file actions.cc.

References _posqueue, and BUTTONS.

00024   : _button(0),
00025     _dragging(false)
00026 {
00027   for (int i=0; i<BUTTONS; ++i)
00028     _posqueue[i] = new ButtonPressAction();
00029 }

ob::Actions::~Actions   [virtual]
 

Destroys the Actions object.

Definition at line 32 of file actions.cc.

References _posqueue, and BUTTONS.

00033 {
00034   for (int i=0; i<BUTTONS; ++i)
00035     delete _posqueue[i];
00036 }


Member Function Documentation

void ob::Actions::buttonPressHandler const XButtonEvent &    e [virtual]
 

Called whenever a button of the pointer is pressed.

Reimplemented from otk::EventHandler.

Definition at line 71 of file actions.cc.

References _button, ob::Openbox::bindings(), otk::EventHandler::buttonPressHandler(), buttonReleaseHandler(), ob::Openbox::findClient(), otk::EventDispatcher::findHandler(), ob::Bindings::fireButton(), insertPress(), ob::WidgetBase::mcontext(), ob::openbox, and ob::Client::screen().

00072 {
00073   otk::EventHandler::buttonPressHandler(e);
00074   insertPress(e);
00075   
00076   // run the PRESS python hook
00077   WidgetBase *w = dynamic_cast<WidgetBase*>
00078     (openbox->findHandler(e.window));
00079   if (!w) return;
00080 
00081   // kill off the Button1Mask etc, only want the modifiers
00082   unsigned int state = e.state & (ControlMask | ShiftMask | Mod1Mask |
00083                                   Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
00084   int screen;
00085   Client *c = openbox->findClient(e.window);
00086   if (c)
00087     screen = c->screen();
00088   else
00089     screen = otk::display->findScreen(e.root)->screen();
00090   MouseData data(screen, c, e.time, state, e.button, w->mcontext(),
00091                  MouseAction::Press);
00092   openbox->bindings()->fireButton(&data);
00093     
00094   if (_button) return; // won't count toward CLICK events
00095 
00096   _button = e.button;
00097 
00098   if (w->mcontext() == MouseContext::Window) {
00099     /*
00100       Because of how events are grabbed on the client window, we can't get
00101       ButtonRelease events, so instead we simply manufacture them here, so that
00102       clicks/doubleclicks etc still work.
00103     */
00104     //XButtonEvent ev = e;
00105     //ev.type = ButtonRelease;
00106     buttonReleaseHandler(e);
00107   }
00108 }

void ob::Actions::buttonReleaseHandler const XButtonEvent &    e [virtual]
 

Called whenever a button of the pointer is released.

Reimplemented from otk::EventHandler.

Definition at line 111 of file actions.cc.

References _button, _dragging, _release, ob::MouseData::action, ob::Openbox::bindings(), ob::Actions::ButtonReleaseAction::button, otk::EventHandler::buttonReleaseHandler(), ob::Openbox::findClient(), otk::EventDispatcher::findHandler(), ob::Bindings::fireButton(), ob::WidgetBase::mcontext(), ob::openbox, ob::python_get_long(), removePress(), ob::Client::screen(), ob::Actions::ButtonReleaseAction::time, and ob::Actions::ButtonReleaseAction::win.

Referenced by buttonPressHandler().

00112 {
00113   otk::EventHandler::buttonReleaseHandler(e);
00114   removePress(e);
00115   
00116   WidgetBase *w = dynamic_cast<WidgetBase*>
00117     (openbox->findHandler(e.window));
00118   if (!w) return;
00119 
00120   // run the RELEASE python hook
00121   // kill off the Button1Mask etc, only want the modifiers
00122   unsigned int state = e.state & (ControlMask | ShiftMask | Mod1Mask |
00123                                   Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
00124   int screen;
00125   Client *c = openbox->findClient(e.window);
00126   if (c)
00127     screen = c->screen();
00128   else
00129     screen = otk::display->findScreen(e.root)->screen();
00130   MouseData data(screen, c, e.time, state, e.button, w->mcontext(),
00131                  MouseAction::Release);
00132   openbox->bindings()->fireButton(&data);
00133 
00134   // not for the button we're watching?
00135   if (_button != e.button) return;
00136 
00137   _button = 0;
00138   _dragging = false;
00139 
00140   // find the area of the window
00141   XWindowAttributes attr;
00142   if (!XGetWindowAttributes(**otk::display, e.window, &attr)) return;
00143 
00144   // if not on the window any more, it isnt a CLICK
00145   if (!(e.same_screen && e.x >= 0 && e.y >= 0 &&
00146         e.x < attr.width && e.y < attr.height))
00147     return;
00148 
00149   // run the CLICK python hook
00150   data.action = MouseAction::Click;
00151   openbox->bindings()->fireButton(&data);
00152     
00153 
00154   // XXX: dont load this every time!!@*
00155   long dblclick;
00156   if (!python_get_long("DOUBLE_CLICK_DELAY", &dblclick))
00157     dblclick = 300;
00158 
00159   if (e.time - _release.time < (unsigned)dblclick &&
00160       _release.win == e.window && _release.button == e.button) {
00161 
00162     // run the DOUBLECLICK python hook
00163     data.action = MouseAction::DoubleClick;
00164     openbox->bindings()->fireButton(&data);
00165     
00166     // reset so you cant triple click for 2 doubleclicks
00167     _release.win = 0;
00168     _release.button = 0;
00169     _release.time = 0;
00170   } else {
00171     // save the button release, might be part of a double click
00172     _release.win = e.window;
00173     _release.button = e.button;
00174     _release.time = e.time;
00175   }
00176 }

void ob::Actions::enterHandler const XCrossingEvent &    e [virtual]
 

Called whenever the pointer enters a window.

Reimplemented from otk::EventHandler.

Definition at line 179 of file actions.cc.

References ob::Openbox::bindings(), otk::EventHandler::enterHandler(), ob::Openbox::findClient(), ob::Bindings::fireEvent(), ob::openbox, and ob::Client::screen().

00180 {
00181   otk::EventHandler::enterHandler(e);
00182   
00183   // run the ENTER python hook
00184   int screen;
00185   Client *c = openbox->findClient(e.window);
00186   if (c)
00187     screen = c->screen();
00188   else
00189     screen = otk::display->findScreen(e.root)->screen();
00190   EventData data(screen, c, EventAction::EnterWindow, e.state);
00191   openbox->bindings()->fireEvent(&data);
00192 }

void ob::Actions::insertPress const XButtonEvent &    e [private]
 

Definition at line 39 of file actions.cc.

References _posqueue, ob::Client::area(), ob::Actions::ButtonPressAction::button, BUTTONS, ob::Openbox::findClient(), and ob::openbox.

Referenced by buttonPressHandler().

00040 {
00041   ButtonPressAction *a = _posqueue[BUTTONS - 1];
00042   // rm'd the last one, shift them all down one
00043   for (int i = BUTTONS-1; i > 0; --i) {
00044     _posqueue[i] = _posqueue[i-1];
00045   }
00046   _posqueue[0] = a;
00047   a->button = e.button;
00048   a->pos.setPoint(e.x_root, e.y_root);
00049 
00050   Client *c = openbox->findClient(e.window);
00051   if (c) a->clientarea = c->area();
00052 }

void ob::Actions::keyPressHandler const XKeyEvent &    e [virtual]
 

Called whenever any key is pressed.

Reimplemented from otk::EventHandler.

Definition at line 211 of file actions.cc.

References ob::Openbox::bindings(), otk::EventHandler::keyPressHandler(), and ob::openbox.

00212 {
00213   otk::EventHandler::keyPressHandler(e);
00214 
00215   // kill off the Button1Mask etc, only want the modifiers
00216   unsigned int state = e.state & (ControlMask | ShiftMask | Mod1Mask |
00217                                   Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
00218   openbox->bindings()->
00219     fireKey(otk::display->findScreen(e.root)->screen(),
00220             state, e.keycode, e.time, KeyAction::Press);
00221 }

void ob::Actions::keyReleaseHandler const XKeyEvent &    e [virtual]
 

Called whenever any key is released.

Reimplemented from otk::EventHandler.

Definition at line 224 of file actions.cc.

References ob::Openbox::bindings(), otk::EventHandler::keyReleaseHandler(), and ob::openbox.

00225 {
00226   otk::EventHandler::keyReleaseHandler(e);
00227 
00228   // kill off the Button1Mask etc, only want the modifiers
00229   unsigned int state = e.state & (ControlMask | ShiftMask | Mod1Mask |
00230                                   Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
00231 
00232   // remove from the state the mask of the modifier being released, if it is
00233   // a modifier key being released (this is a little ugly..)
00234   const XModifierKeymap *map = otk::display->modifierMap();
00235   const int mask_table[] = {
00236     ShiftMask, LockMask, ControlMask, Mod1Mask,
00237     Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
00238   };
00239   KeyCode *kp = map->modifiermap;
00240   for (int i = 0, n = sizeof(mask_table)/sizeof(mask_table[0]); i < n; ++i) {
00241     for (int k = 0; k < map->max_keypermod; ++k) {
00242       if (*kp == e.keycode) { // found the keycode
00243         state &= ~mask_table[i]; // remove the mask for it
00244         i = n; // cause the first loop to break;
00245         break; // get outta here!
00246       }
00247       ++kp;
00248     }
00249   }
00250   
00251   openbox->bindings()->
00252     fireKey(otk::display->findScreen(e.root)->screen(),
00253             state, e.keycode, e.time, KeyAction::Release);
00254 }

void ob::Actions::leaveHandler const XCrossingEvent &    e [virtual]
 

Called whenever the pointer leaves a window.

Reimplemented from otk::EventHandler.

Definition at line 195 of file actions.cc.

References ob::Openbox::bindings(), ob::Openbox::findClient(), ob::Bindings::fireEvent(), otk::EventHandler::leaveHandler(), ob::openbox, and ob::Client::screen().

00196 {
00197   otk::EventHandler::leaveHandler(e);
00198 
00199   // run the LEAVE python hook
00200   int screen;
00201   Client *c = openbox->findClient(e.window);
00202   if (c)
00203     screen = c->screen();
00204   else
00205     screen = otk::display->findScreen(e.root)->screen();
00206   EventData data(screen, c, EventAction::LeaveWindow, e.state);
00207   openbox->bindings()->fireEvent(&data);
00208 }

void ob::Actions::motionHandler const XMotionEvent &    e [virtual]
 

Called whenever the pointer moved.

Reimplemented from otk::EventHandler.

Definition at line 257 of file actions.cc.

References _dragging, _posqueue, ob::Openbox::bindings(), ob::Actions::ButtonPressAction::button, ob::Openbox::findClient(), otk::EventDispatcher::findHandler(), ob::Bindings::fireButton(), ob::WidgetBase::mcontext(), otk::EventHandler::motionHandler(), ob::openbox, ob::Actions::ButtonPressAction::pos, ob::python_get_long(), ob::Client::screen(), otk::Point::x(), and otk::Point::y().

00258 {
00259   otk::EventHandler::motionHandler(e);
00260 
00261   if (!e.same_screen) return; // this just gets stupid
00262 
00263   int x_root = e.x_root, y_root = e.y_root;
00264   
00265   // compress changes to a window into a single change
00266   XEvent ce;
00267   while (XCheckTypedEvent(**otk::display, e.type, &ce)) {
00268     if (ce.xmotion.window != e.window) {
00269       XPutBackEvent(**otk::display, &ce);
00270       break;
00271     } else {
00272       x_root = e.x_root;
00273       y_root = e.y_root;
00274     }
00275   }
00276 
00277   WidgetBase *w = dynamic_cast<WidgetBase*>
00278     (openbox->findHandler(e.window));
00279   if (!w) return;
00280 
00281   if (!_dragging) {
00282     long threshold;
00283     int dx = x_root - _posqueue[0]->pos.x();
00284     int dy = y_root - _posqueue[0]->pos.y();
00285     // XXX: dont get this from python every time!
00286     if (!python_get_long("DRAG_THRESHOLD", &threshold))
00287       threshold = 0;
00288     if (!(std::abs(dx) >= threshold || std::abs(dy) >= threshold))
00289       return; // not at the threshold yet
00290   }
00291   _dragging = true; // in a drag now
00292   
00293   // check if the movement is more than the threshold
00294 
00295   // run the MOTION python hook
00296   // kill off the Button1Mask etc, only want the modifiers
00297   unsigned int state = e.state & (ControlMask | ShiftMask | Mod1Mask |
00298                                   Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
00299   unsigned int button = _posqueue[0]->button;
00300   int screen;
00301   Client *c = openbox->findClient(e.window);
00302   if (c)
00303     screen = c->screen();
00304   else
00305     screen = otk::display->findScreen(e.root)->screen();
00306   MouseData data(screen, c, e.time, state, button, w->mcontext(),
00307                  MouseAction::Motion, x_root, y_root,
00308                  _posqueue[0]->pos, _posqueue[0]->clientarea);
00309   openbox->bindings()->fireButton(&data);
00310 }

void ob::Actions::removePress const XButtonEvent &    e [private]
 

Definition at line 54 of file actions.cc.

References _posqueue, ob::Actions::ButtonPressAction::button, and BUTTONS.

Referenced by buttonReleaseHandler().

00055 {
00056   int i;
00057   ButtonPressAction *a = 0;
00058   for (i=0; i<BUTTONS-1; ++i)
00059     if (_posqueue[i]->button == e.button) {
00060       a = _posqueue[i];
00061       break;
00062     }
00063   if (a) { // found one, remove it and shift the rest up one
00064     for (; i < BUTTONS-1; ++i)
00065       _posqueue[i] = _posqueue[i+1];
00066     _posqueue[BUTTONS-1] = a;
00067   }
00068   _posqueue[BUTTONS-1]->button = 0;
00069 }


Member Data Documentation

unsigned int ob::Actions::_button [private]
 

The mouse button currently being watched from a press for a CLICK.

Definition at line 50 of file actions.hh.

Referenced by buttonPressHandler(), and buttonReleaseHandler().

bool ob::Actions::_dragging [private]
 

This is set to true once a drag has started and false when done to make sure the threshold isnt checked anymore once a drag is underway.

Definition at line 60 of file actions.hh.

Referenced by buttonReleaseHandler(), and motionHandler().

ButtonPressAction* ob::Actions::_posqueue[BUTTONS] [private]
 

The point where the mouse was when each mouse button was pressed.

Used for motion events as the starting position.

Definition at line 57 of file actions.hh.

Referenced by Actions(), insertPress(), motionHandler(), removePress(), and ~Actions().

ButtonReleaseAction ob::Actions::_release [private]
 

The last button release processed for CLICKs.

Definition at line 52 of file actions.hh.

Referenced by buttonReleaseHandler().

const int ob::Actions::BUTTONS = 5 [static, private]
 

Definition at line 21 of file actions.cc.

Referenced by Actions(), insertPress(), removePress(), and ~Actions().


The documentation for this class was generated from the following files:
Generated on Tue Feb 4 23:00:11 2003 for Openbox by doxygen1.3-rc2