diff options
| author | Dana Jansens <danakj@orodu.net> | 2002-12-25 22:02:34 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2002-12-25 22:02:34 +0000 |
| commit | 2ae2b257d39ea62640c2590f794e4275c6db1cd4 (patch) | |
| tree | f26abe4a0601d263fbc460eddc012c1d674c868b /src | |
| parent | 3c61812e588fb3c34d0713d7f82ccbf21091f032 (diff) | |
might not compile... ob uses its own widgets now, which subclass only the base otk widget. working on compressing focus events and handling them etc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/backgroundwidget.cc | 58 | ||||
| -rw-r--r-- | src/backgroundwidget.hh | 8 | ||||
| -rw-r--r-- | src/buttonwidget.cc | 94 | ||||
| -rw-r--r-- | src/buttonwidget.hh | 13 | ||||
| -rw-r--r-- | src/client.cc | 36 | ||||
| -rw-r--r-- | src/client.hh | 7 | ||||
| -rw-r--r-- | src/frame.cc | 52 | ||||
| -rw-r--r-- | src/frame.hh | 9 | ||||
| -rw-r--r-- | src/labelwidget.cc | 92 | ||||
| -rw-r--r-- | src/labelwidget.hh | 22 | ||||
| -rw-r--r-- | src/main.cc | 16 | ||||
| -rw-r--r-- | src/openbox.cc | 25 | ||||
| -rw-r--r-- | src/openbox.hh | 28 | ||||
| -rw-r--r-- | src/openbox.i | 1 | ||||
| -rw-r--r-- | src/openbox_wrap.cc | 182 | ||||
| -rw-r--r-- | src/python.cc | 21 | ||||
| -rw-r--r-- | src/python.hh | 5 | ||||
| -rw-r--r-- | src/screen.cc | 8 | ||||
| -rw-r--r-- | src/screen.hh | 6 |
19 files changed, 593 insertions, 90 deletions
diff --git a/src/backgroundwidget.cc b/src/backgroundwidget.cc index 7d715f55..8b63b44d 100644 --- a/src/backgroundwidget.cc +++ b/src/backgroundwidget.cc @@ -10,7 +10,7 @@ namespace ob { OBBackgroundWidget::OBBackgroundWidget(otk::OtkWidget *parent, OBWidget::WidgetType type) - : otk::OtkFocusWidget(parent), + : otk::OtkWidget(parent), OBWidget(type) { } @@ -21,37 +21,67 @@ OBBackgroundWidget::~OBBackgroundWidget() } -void OBBackgroundWidget::setStyle(otk::Style *style) +void OBBackgroundWidget::setTextures() { switch (type()) { case Type_Titlebar: - setTexture(style->getTitleFocus()); - setUnfocusTexture(style->getTitleUnfocus()); - setBorderColor(style->getBorderColor()); + if (_focused) + setTexture(_style->getTitleFocus()); + else + setTexture(_style->getTitleUnfocus()); + break; + case Type_Handle: + if (_focused) + setTexture(_style->getHandleFocus()); + else + setTexture(_style->getHandleUnfocus()); break; + case Type_Plate: + if (_focused) + setBorderColor(&_style->getFrameFocus()->color()); + else + setBorderColor(&_style->getFrameUnfocus()->color()); + break; + default: + assert(false); // there's no other background widgets! + } +} + + +void OBBackgroundWidget::setStyle(otk::Style *style) +{ + OtkWidget::setStyle(style); + setTextures(); + switch (type()) { + case Type_Titlebar: case Type_Handle: - setTexture(style->getHandleFocus()); - setUnfocusTexture(style->getHandleUnfocus()); - setBorderColor(style->getBorderColor()); + setBorderColor(_style->getBorderColor()); break; case Type_Plate: - setBorderColor(&style->getFrameFocus()->color()); - setUnfocusBorderColor(&style->getFrameUnfocus()->color()); break; default: assert(false); // there's no other background widgets! } +} + + +void OBBackgroundWidget::focus() +{ + otk::OtkWidget::focus(); + setTextures(); +} + - otk::OtkFocusWidget::setStyle(style); +void OBBackgroundWidget::unfocus() +{ + otk::OtkWidget::unfocus(); + setTextures(); } void OBBackgroundWidget::adjust() { - otk::OtkFocusWidget::adjust(); - // XXX: adjust shit } - } diff --git a/src/backgroundwidget.hh b/src/backgroundwidget.hh index 0cbfb3fa..7b698c15 100644 --- a/src/backgroundwidget.hh +++ b/src/backgroundwidget.hh @@ -2,14 +2,15 @@ #ifndef __obbackgroundwidget_hh #define __obbackgroundwidget_hh -#include "otk/focuswidget.hh" +#include "otk/widget.hh" #include "widget.hh" namespace ob { -class OBBackgroundWidget : public otk::OtkFocusWidget, public OBWidget +class OBBackgroundWidget : public otk::OtkWidget, public OBWidget { private: + void setTextures(); public: OBBackgroundWidget(otk::OtkWidget *parent, OBWidget::WidgetType type); @@ -18,6 +19,9 @@ public: virtual void setStyle(otk::Style *style); virtual void adjust(); + + virtual void focus(); + virtual void unfocus(); }; } diff --git a/src/buttonwidget.cc b/src/buttonwidget.cc index 867cc5be..853b0339 100644 --- a/src/buttonwidget.cc +++ b/src/buttonwidget.cc @@ -10,8 +10,10 @@ namespace ob { OBButtonWidget::OBButtonWidget(otk::OtkWidget *parent, OBWidget::WidgetType type) - : otk::OtkButton(parent), - OBWidget(type) + : otk::OtkWidget(parent), + OBWidget(type), + _pressed(false), + _button(0) { } @@ -21,36 +23,98 @@ OBButtonWidget::~OBButtonWidget() } +void OBButtonWidget::setTextures() +{ + switch (type()) { + case Type_LeftGrip: + case Type_RightGrip: + if (_focused) + setTexture(_style->getGripFocus()); + else + setTexture(_style->getGripUnfocus()); + break; + case Type_StickyButton: + case Type_CloseButton: + case Type_MaximizeButton: + case Type_IconifyButton: + if (_pressed) { + if (_focused) + setTexture(_style->getButtonPressedFocus()); + else + setTexture(_style->getButtonPressedUnfocus()); + } else { + if (_focused) + setTexture(_style->getButtonFocus()); + else + setTexture(_style->getButtonUnfocus()); + } + break; + default: + assert(false); // there's no other button widgets! + } +} + + void OBButtonWidget::setStyle(otk::Style *style) { - otk::OtkButton::setStyle(style); + otk::OtkWidget::setStyle(style); + setTextures(); switch (type()) { case Type_LeftGrip: case Type_RightGrip: - setTexture(style->getGripFocus()); - setUnfocusTexture(style->getGripUnfocus()); - setPressedFocusTexture(style->getGripFocus()); - setPressedUnfocusTexture(style->getGripUnfocus()); - setTexture(style->getGripFocus()); - setUnfocusTexture(style->getGripUnfocus()); - setPressedFocusTexture(style->getGripFocus()); - setPressedUnfocusTexture(style->getGripUnfocus()); setBorderColor(_style->getBorderColor()); - setUnfocusBorderColor(style->getBorderColor()); break; - default: + case Type_StickyButton: + case Type_CloseButton: + case Type_MaximizeButton: + case Type_IconifyButton: break; + default: + assert(false); // there's no other button widgets! } } -void OBButtonWidget::adjust() +void OBButtonWidget::focus() { - otk::OtkButton::adjust(); + otk::OtkWidget::focus(); + setTextures(); +} + +void OBButtonWidget::unfocus() +{ + otk::OtkWidget::unfocus(); + setTextures(); +} + + +void OBButtonWidget::adjust() +{ // XXX: adjust shit } +void OBButtonWidget::buttonPressHandler(const XButtonEvent &e) +{ + OtkWidget::buttonPressHandler(e); + if (_button) return; + _button = e.button; + _pressed = true; + setTextures(); + update(); +} + + +void OBButtonWidget::buttonReleaseHandler(const XButtonEvent &e) +{ + OtkWidget::buttonPressHandler(e); + if (e.button != _button) return; + _button = 0; + _pressed = false; + setTextures(); + update(); +} + } diff --git a/src/buttonwidget.hh b/src/buttonwidget.hh index bb23dd90..66a9cf37 100644 --- a/src/buttonwidget.hh +++ b/src/buttonwidget.hh @@ -2,14 +2,17 @@ #ifndef __obbuttonwidget_hh #define __obbuttonwidget_hh -#include "otk/button.hh" +#include "otk/widget.hh" #include "widget.hh" namespace ob { -class OBButtonWidget : public otk::OtkButton, public OBWidget +class OBButtonWidget : public otk::OtkWidget, public OBWidget { private: + void setTextures(); + bool _pressed; + unsigned int _button; public: OBButtonWidget(otk::OtkWidget *parent, OBWidget::WidgetType type); @@ -18,6 +21,12 @@ public: virtual void setStyle(otk::Style *style); virtual void adjust(); + + virtual void focus(); + virtual void unfocus(); + + virtual void buttonPressHandler(const XButtonEvent &e); + virtual void buttonReleaseHandler(const XButtonEvent &e); }; } diff --git a/src/client.cc b/src/client.cc index a22a18a6..2f966cee 100644 --- a/src/client.cc +++ b/src/client.cc @@ -40,6 +40,8 @@ OBClient::OBClient(int screen, Window window) _wmstate = NormalState; // no default decors or functions, each has to be enabled _decorations = _functions = 0; + // start unfocused + _focused = false; getArea(); getDesktop(); @@ -460,6 +462,9 @@ void OBClient::updateTitle() if (_title.empty()) _title = _("Unnamed Window"); + + if (frame) + frame->setTitle(_title); } @@ -859,6 +864,37 @@ void OBClient::close() } +bool OBClient::focus() +{ + if (!_can_focus) return false; + + XSetInputFocus(otk::OBDisplay::display, _window, RevertToNone, CurrentTime); + return true; +} + + +void OBClient::focusHandler(const XFocusChangeEvent &) +{ + frame->focus(); + _focused = true; + + Openbox::instance->setFocusedClient(this); +} + + +void OBClient::unfocusHandler(const XFocusChangeEvent &) +{ + frame->unfocus(); + _focused = false; + + if (Openbox::instance->focusedClient() == this) { + printf("UNFOCUSING\n"); + Openbox::instance->setFocusedClient(0); + } else + printf("UNFOCUSED ALREADY COULDNT UNFOCUS\n"); +} + + void OBClient::configureRequestHandler(const XConfigureRequestEvent &e) { OtkEventHandler::configureRequestHandler(e); diff --git a/src/client.hh b/src/client.hh index eeb04232..61f7b071 100644 --- a/src/client.hh +++ b/src/client.hh @@ -234,6 +234,8 @@ private: bool _urgent; //! Notify the window when it receives focus? bool _focus_notify; + //! Does the client window have the input focus? + bool _focused; //! The window uses shape extension to be non-rectangular? bool _shaped; @@ -431,7 +433,12 @@ public: //! Request the client to close its window. void close(); + + //! Attempt to focus the client window + bool focus(); + virtual void focusHandler(const XFocusChangeEvent &e); + virtual void unfocusHandler(const XFocusChangeEvent &e); virtual void propertyHandler(const XPropertyEvent &e); virtual void clientMessageHandler(const XClientMessageEvent &e); virtual void shapeHandler(const XShapeEvent &e); diff --git a/src/frame.cc b/src/frame.cc index 4e30a1f5..fed6132e 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -43,31 +43,15 @@ OBFrame::OBFrame(OBClient *client, otk::Style *style) XSelectInput(otk::OBDisplay::display, window(), OBFrame::event_mask); - unmanaged(); - _titlebar.unmanaged(); - _button_close.unmanaged(); - _button_iconify.unmanaged(); - _button_max.unmanaged(); - _button_stick.unmanaged(); - _label.unmanaged(); - _handle.unmanaged(); - _grip_left.unmanaged(); - _grip_right.unmanaged(); - _plate.unmanaged(); - _grip_left.setCursor(Openbox::instance->cursors().ll_angle); _grip_right.setCursor(Openbox::instance->cursors().lr_angle); - _button_close.setText("X"); - _button_iconify.setText("I"); - _button_max.setText("M"); - _button_stick.setText("S"); _label.setText(_client->title()); _style = 0; setStyle(style); - //XXX: uncomment me unfocus(); // stuff starts out focused in otk + otk::OtkWidget::unfocus(); // stuff starts out appearing focused in otk _plate.show(); // the other stuff is shown based on decor settings @@ -81,6 +65,13 @@ OBFrame::~OBFrame() } +void OBFrame::setTitle(const std::string &text) +{ + _label.setText(text); + _label.update(); +} + + void OBFrame::setStyle(otk::Style *style) { assert(style); @@ -97,9 +88,7 @@ void OBFrame::setStyle(otk::Style *style) _style = style; - // XXX: change when focus changes! - XSetWindowBorder(otk::OBDisplay::display, window(), - _style->getBorderColor()->pixel()); + setBorderColor(_style->getBorderColor()); // if !replace, then adjust() will get called after the client is grabbed! if (replace) { @@ -110,6 +99,25 @@ void OBFrame::setStyle(otk::Style *style) } +void OBFrame::focus() +{ + otk::OtkWidget::focus(); + update(); +} + + +void OBFrame::unfocus() +{ + otk::OtkWidget::unfocus(); + update(); +} + + +void OBFrame::adjust() +{ +} + + void OBFrame::adjustSize() { // XXX: only if not overridden or something!!! MORE LOGIC HERE!! @@ -142,13 +150,13 @@ void OBFrame::adjustSize() _titlebar.setGeometry(-bwidth, -bwidth, width, - (_style->getFont().height() + + (_style->getFont()->height() + _style->getBevelWidth() * 2)); _innersize.top += _titlebar.height() + bwidth; // set the label size _label.setGeometry(0, _style->getBevelWidth(), - width, _style->getFont().height()); + width, _style->getFont()->height()); // set the buttons sizes if (_decorations & OBClient::Decor_Iconify) _button_iconify.setGeometry(0, _style->getBevelWidth() + 1, diff --git a/src/frame.hh b/src/frame.hh index 37eee7ea..5f70b643 100644 --- a/src/frame.hh +++ b/src/frame.hh @@ -93,6 +93,15 @@ public: //! Set the style to decorate the frame with virtual void setStyle(otk::Style *style); + //! Realign children + virtual void adjust(); + //! Displays focused decorations + virtual void focus(); + //! Displays unfocused decorations + virtual void unfocus(); + + void setTitle(const std::string &text); + //! Update the frame's size to match the client void adjustSize(); //! Update the frame's position to match the client diff --git a/src/labelwidget.cc b/src/labelwidget.cc index 9b18c0a9..5a33cf3d 100644 --- a/src/labelwidget.cc +++ b/src/labelwidget.cc @@ -4,37 +4,115 @@ # include "../config.h" #endif +#include "otk/screeninfo.hh" +#include "otk/display.hh" #include "labelwidget.hh" namespace ob { OBLabelWidget::OBLabelWidget(otk::OtkWidget *parent, OBWidget::WidgetType type) - : otk::OtkFocusLabel(parent), + : otk::OtkWidget(parent), OBWidget(type) { + const otk::ScreenInfo *info = otk::OBDisplay::screenInfo(_screen); + _xftdraw = XftDrawCreate(otk::OBDisplay::display, _window, info->visual(), + info->colormap()); } OBLabelWidget::~OBLabelWidget() { + XftDrawDestroy(_xftdraw); +} + + +void OBLabelWidget::setText(const std::string &text) +{ + _text = text; + _dirty = true; +} + + +void OBLabelWidget::setTextures() +{ + if (_focused) { + setTexture(_style->getLabelFocus()); + _text_color = _style->getTextFocus(); + } else { + setTexture(_style->getLabelUnfocus()); + _text_color = _style->getTextUnfocus(); + } } void OBLabelWidget::setStyle(otk::Style *style) { - setTexture(style->getLabelFocus()); - setUnfocusTexture(style->getLabelUnfocus()); + OtkWidget::setStyle(style); + setTextures(); + _font = style->getFont(); + assert(_font); + _sidemargin = style->getBevelWidth() * 2; + _justify = style->textJustify(); +} + - otk::OtkFocusLabel::setStyle(style); +void OBLabelWidget::focus() +{ + otk::OtkWidget::focus(); + setTextures(); } -void OBLabelWidget::adjust() +void OBLabelWidget::unfocus() { - otk::OtkFocusLabel::adjust(); + otk::OtkWidget::unfocus(); + setTextures(); +} - // XXX: adjust shit + +void OBLabelWidget::update() +{ + if (_dirty) { + std::string t = _text; + int x = _sidemargin; // x coord for the text + + // find a string that will fit inside the area for text + int max_length = width() - _sidemargin * 2; + if (max_length <= 0) { + t = ""; // can't fit anything + } else { + size_t text_len = t.size(); + int length; + + do { + t.resize(text_len); + length = _font->measureString(t); + } while (length > max_length && text_len-- > 0); + + // justify the text + switch (_justify) { + case otk::Style::RightJustify: + x += max_length - length; + break; + case otk::Style::CenterJustify: + x += (max_length - length) / 2; + break; + case otk::Style::LeftJustify: + break; + } + } + + OtkWidget::update(); + + _font->drawString(_xftdraw, x, 0, *_text_color, t); + } else + OtkWidget::update(); } +void OBLabelWidget::adjust() +{ + // XXX: adjust shit +} + } diff --git a/src/labelwidget.hh b/src/labelwidget.hh index def81fef..01662f85 100644 --- a/src/labelwidget.hh +++ b/src/labelwidget.hh @@ -2,14 +2,24 @@ #ifndef __oblabelwidget_hh #define __oblabelwidget_hh -#include "otk/focuslabel.hh" +#include "otk/widget.hh" +#include "otk/font.hh" +#include "otk/style.hh" #include "widget.hh" namespace ob { -class OBLabelWidget : public otk::OtkFocusLabel, public OBWidget +class OBLabelWidget : public otk::OtkWidget, public OBWidget { private: + void setTextures(); + const otk::BFont *_font; + otk::BColor *_text_color; + int _sidemargin; + otk::Style::TextJustify _justify; + std::string _text; + //! Object used by Xft to render to the drawable + XftDraw *_xftdraw; public: OBLabelWidget(otk::OtkWidget *parent, OBWidget::WidgetType type); @@ -18,6 +28,14 @@ public: virtual void setStyle(otk::Style *style); virtual void adjust(); + + virtual void focus(); + virtual void unfocus(); + + virtual void update(); + + inline const std::string &text() const { return _text; } + void setText(const std::string &text); }; } diff --git a/src/main.cc b/src/main.cc index 5d878d79..a8312af5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -13,32 +13,20 @@ extern "C" { # include <locale.h> #endif // HAVE_LOCALE_H -#include <guile/gh.h> - #include "gettext.h" } #include <string> using std::string; -#include "blackbox.hh" #include "openbox.hh" -void main_prog(int argc, char **argv) { - ob::Openbox openbox(argc, argv); - //ob::Blackbox blackbox(argc, argv, 0); - - //Blackbox blackbox(argv, session_display, rc_file); - openbox.eventLoop(); -} - int main(int argc, char **argv) { // initialize the locale setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); - // start up guile - //gh_enter(argc, argv, main_prog); - main_prog(argc, argv); + ob::Openbox openbox(argc, argv); + openbox.eventLoop(); } diff --git a/src/openbox.cc b/src/openbox.cc index 41f0c7b1..ff42f58b 100644 --- a/src/openbox.cc +++ b/src/openbox.cc @@ -108,6 +108,8 @@ Openbox::Openbox(int argc, char **argv) _doshutdown = false; _rcfilepath = otk::expandTilde("~/.openbox/rc3"); _scriptfilepath = otk::expandTilde("~/.openbox/user.py"); + _focused_client = 0; + _sync = false; parseCommandLine(argc, argv); @@ -128,7 +130,9 @@ Openbox::Openbox(int argc, char **argv) // open the X display (and gets some info about it, and its screens) otk::OBDisplay::initialize(_displayreq); assert(otk::OBDisplay::display); - + + XSynchronize(otk::OBDisplay::display, _sync); + // set up the signal handler action.sa_handler = Openbox::signalHandler; action.sa_mask = sigset_t(); @@ -181,6 +185,10 @@ Openbox::Openbox(int argc, char **argv) ::exit(1); } + // set up input focus + _focused_screen = _screens[0]; + setFocusedClient(0); + _state = State_Normal; // done starting } @@ -223,6 +231,8 @@ void Openbox::parseCommandLine(int argc, char **argv) err = true; else _scriptfilepath = argv[i]; + } else if (arg == "-sync") { + _sync = true; } else if (arg == "-version") { showVersion(); ::exit(0); @@ -321,5 +331,18 @@ OBClient *Openbox::findClient(Window window) return (OBClient*) 0; } + +void Openbox::setFocusedClient(OBClient *c) +{ + _focused_client = c; + if (c) { + _focused_screen = _screens[c->screen()]; + } else { + assert(_focused_screen); + XSetInputFocus(otk::OBDisplay::display, _focused_screen->focuswindow(), + RevertToNone, CurrentTime); + } +} + } diff --git a/src/openbox.hh b/src/openbox.hh index 1489ffb7..976a4977 100644 --- a/src/openbox.hh +++ b/src/openbox.hh @@ -121,6 +121,9 @@ private: //! The action interface through which all user-available actions occur OBActions *_actions; + //! Run the application in synchronous mode? (for debugging) + bool _sync; + //! The running state of the window manager RunState _state; @@ -133,6 +136,19 @@ private: //! The configuration of the application. TEMPORARY otk::Configuration _config; + //! The client with input focus + /*! + Updated by the clients themselves. + */ + OBClient *_focused_client; + + //! The screen with input focus + /*! + Updated by the clients when they update the Openbox::focused_client + property. + */ + OBScreen *_focused_screen; + //! Parses the command line used when executing this application void parseCommandLine(int argv, char **argv); //! Displays the version string to stdout @@ -203,6 +219,18 @@ public: //! Finds an OBClient based on its window id OBClient *findClient(Window window); + //! The client with input focus + inline OBClient *focusedClient() { return _focused_client; } + + //! Change the client which has focus. + /*! + This is called by the clients themselves when their focus state changes. + */ + void setFocusedClient(OBClient *c); + + //! The screen with input focus + inline OBScreen *focusedScreen() { return _focused_screen; } + //! Requests that the window manager exit /*! Causes the Openbox::eventLoop function to stop looping, so that the window diff --git a/src/openbox.i b/src/openbox.i index ef82956b..20c8ea06 100644 --- a/src/openbox.i +++ b/src/openbox.i @@ -53,6 +53,7 @@ %} %ignore ob::python_callback; %rename(register) ob::python_register; +%rename(preregister) ob::python_preregister; %rename(unregister) ob::python_unregister; %ignore ob::OBScreen::clients; diff --git a/src/openbox_wrap.cc b/src/openbox_wrap.cc index b95ae259..12cd7e20 100644 --- a/src/openbox_wrap.cc +++ b/src/openbox_wrap.cc @@ -658,17 +658,18 @@ SWIG_InstallConstants(PyObject *d, swig_const_info constants[]) { #define SWIGTYPE_p_otk__OtkEventHandler swig_types[10] #define SWIGTYPE_p_otk__Rect swig_types[11] #define SWIGTYPE_p_ob__OBWidget swig_types[12] -#define SWIGTYPE_p_XClientMessageEvent swig_types[13] -#define SWIGTYPE_p_otk__OBProperty swig_types[14] -#define SWIGTYPE_p_otk__OtkEventDispatcher swig_types[15] -#define SWIGTYPE_p_XPropertyEvent swig_types[16] -#define SWIGTYPE_p_XDestroyWindowEvent swig_types[17] -#define SWIGTYPE_p_otk__BImageControl swig_types[18] -#define SWIGTYPE_p_PyObject swig_types[19] -#define SWIGTYPE_p_ob__MwmHints swig_types[20] -#define SWIGTYPE_p_otk__Configuration swig_types[21] -#define SWIGTYPE_p_XUnmapEvent swig_types[22] -static swig_type_info *swig_types[24]; +#define SWIGTYPE_p_XFocusChangeEvent swig_types[13] +#define SWIGTYPE_p_XClientMessageEvent swig_types[14] +#define SWIGTYPE_p_otk__OBProperty swig_types[15] +#define SWIGTYPE_p_otk__OtkEventDispatcher swig_types[16] +#define SWIGTYPE_p_XPropertyEvent swig_types[17] +#define SWIGTYPE_p_XDestroyWindowEvent swig_types[18] +#define SWIGTYPE_p_otk__BImageControl swig_types[19] +#define SWIGTYPE_p_PyObject swig_types[20] +#define SWIGTYPE_p_ob__MwmHints swig_types[21] +#define SWIGTYPE_p_otk__Configuration swig_types[22] +#define SWIGTYPE_p_XUnmapEvent swig_types[23] +static swig_type_info *swig_types[25]; /* -------- TYPES TABLE (END) -------- */ @@ -1229,6 +1230,59 @@ static PyObject *_wrap_Openbox_findClient(PyObject *self, PyObject *args) { } +static PyObject *_wrap_Openbox_focusedClient(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::Openbox *arg1 = (ob::Openbox *) 0 ; + ob::OBClient *result; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:Openbox_focusedClient",&obj0)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Openbox,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + result = (ob::OBClient *)(arg1)->focusedClient(); + + resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ob__OBClient, 0); + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_Openbox_setFocusedClient(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::Openbox *arg1 = (ob::Openbox *) 0 ; + ob::OBClient *arg2 = (ob::OBClient *) 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"OO:Openbox_setFocusedClient",&obj0,&obj1)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Openbox,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + (arg1)->setFocusedClient(arg2); + + Py_INCREF(Py_None); resultobj = Py_None; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_Openbox_focusedScreen(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::Openbox *arg1 = (ob::Openbox *) 0 ; + ob::OBScreen *result; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:Openbox_focusedScreen",&obj0)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__Openbox,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + result = (ob::OBScreen *)(arg1)->focusedScreen(); + + resultobj = SWIG_NewPointerObj((void *) result, SWIGTYPE_p_ob__OBScreen, 0); + return resultobj; + fail: + return NULL; +} + + static PyObject *_wrap_Openbox_shutdown(PyObject *self, PyObject *args) { PyObject *resultobj; ob::Openbox *arg1 = (ob::Openbox *) 0 ; @@ -1358,6 +1412,23 @@ static PyObject *_wrap_OBScreen_style(PyObject *self, PyObject *args) { } +static PyObject *_wrap_OBScreen_focuswindow(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::OBScreen *arg1 = (ob::OBScreen *) 0 ; + Window result; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:OBScreen_focuswindow",&obj0)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBScreen,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + result = (Window)((ob::OBScreen const *)arg1)->focuswindow(); + + resultobj = PyInt_FromLong((long)result); + return resultobj; + fail: + return NULL; +} + + static PyObject *_wrap_OBScreen_addStrut(PyObject *self, PyObject *args) { PyObject *resultobj; ob::OBScreen *arg1 = (ob::OBScreen *) 0 ; @@ -2172,6 +2243,67 @@ static PyObject *_wrap_OBClient_close(PyObject *self, PyObject *args) { } +static PyObject *_wrap_OBClient_focus(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::OBClient *arg1 = (ob::OBClient *) 0 ; + bool result; + PyObject * obj0 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"O:OBClient_focus",&obj0)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + result = (bool)(arg1)->focus(); + + resultobj = PyInt_FromLong((long)result); + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_OBClient_focusHandler(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::OBClient *arg1 = (ob::OBClient *) 0 ; + XFocusChangeEvent *arg2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"OO:OBClient_focusHandler",&obj0,&obj1)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_XFocusChangeEvent,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + if (arg2 == NULL) { + PyErr_SetString(PyExc_TypeError,"null reference"); SWIG_fail; + } + (arg1)->focusHandler((XFocusChangeEvent const &)*arg2); + + Py_INCREF(Py_None); resultobj = Py_None; + return resultobj; + fail: + return NULL; +} + + +static PyObject *_wrap_OBClient_unfocusHandler(PyObject *self, PyObject *args) { + PyObject *resultobj; + ob::OBClient *arg1 = (ob::OBClient *) 0 ; + XFocusChangeEvent *arg2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"OO:OBClient_unfocusHandler",&obj0,&obj1)) goto fail; + if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_ob__OBClient,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + if ((SWIG_ConvertPtr(obj1,(void **) &arg2, SWIGTYPE_p_XFocusChangeEvent,SWIG_POINTER_EXCEPTION | 0 )) == -1) SWIG_fail; + if (arg2 == NULL) { + PyErr_SetString(PyExc_TypeError,"null reference"); SWIG_fail; + } + (arg1)->unfocusHandler((XFocusChangeEvent const &)*arg2); + + Py_INCREF(Py_None); resultobj = Py_None; + return resultobj; + fail: + return NULL; +} + + static PyObject *_wrap_OBClient_propertyHandler(PyObject *self, PyObject *args) { PyObject *resultobj; ob::OBClient *arg1 = (ob::OBClient *) 0 ; @@ -2329,6 +2461,24 @@ static PyObject *_wrap_register(PyObject *self, PyObject *args) { } +static PyObject *_wrap_preregister(PyObject *self, PyObject *args) { + PyObject *resultobj; + int arg1 ; + PyObject *arg2 = (PyObject *) 0 ; + bool result; + PyObject * obj1 = 0 ; + + if(!PyArg_ParseTuple(args,(char *)"iO:preregister",&arg1,&obj1)) goto fail; + arg2 = obj1; + result = (bool)ob::python_preregister(arg1,arg2); + + resultobj = PyInt_FromLong((long)result); + return resultobj; + fail: + return NULL; +} + + static PyObject *_wrap_unregister(PyObject *self, PyObject *args) { PyObject *resultobj; int arg1 ; @@ -2371,6 +2521,9 @@ static PyMethodDef SwigMethods[] = { { (char *)"Openbox_addClient", _wrap_Openbox_addClient, METH_VARARGS }, { (char *)"Openbox_removeClient", _wrap_Openbox_removeClient, METH_VARARGS }, { (char *)"Openbox_findClient", _wrap_Openbox_findClient, METH_VARARGS }, + { (char *)"Openbox_focusedClient", _wrap_Openbox_focusedClient, METH_VARARGS }, + { (char *)"Openbox_setFocusedClient", _wrap_Openbox_setFocusedClient, METH_VARARGS }, + { (char *)"Openbox_focusedScreen", _wrap_Openbox_focusedScreen, METH_VARARGS }, { (char *)"Openbox_shutdown", _wrap_Openbox_shutdown, METH_VARARGS }, { (char *)"Openbox_swigregister", Openbox_swigregister, METH_VARARGS }, { (char *)"OBScreen_client", _wrap_OBScreen_client, METH_VARARGS }, @@ -2379,6 +2532,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"OBScreen_imageControl", _wrap_OBScreen_imageControl, METH_VARARGS }, { (char *)"OBScreen_area", _wrap_OBScreen_area, METH_VARARGS }, { (char *)"OBScreen_style", _wrap_OBScreen_style, METH_VARARGS }, + { (char *)"OBScreen_focuswindow", _wrap_OBScreen_focuswindow, METH_VARARGS }, { (char *)"OBScreen_addStrut", _wrap_OBScreen_addStrut, METH_VARARGS }, { (char *)"OBScreen_removeStrut", _wrap_OBScreen_removeStrut, METH_VARARGS }, { (char *)"OBScreen_loadStyle", _wrap_OBScreen_loadStyle, METH_VARARGS }, @@ -2425,6 +2579,9 @@ static PyMethodDef SwigMethods[] = { { (char *)"OBClient_move", _wrap_OBClient_move, METH_VARARGS }, { (char *)"OBClient_resize", _wrap_OBClient_resize, METH_VARARGS }, { (char *)"OBClient_close", _wrap_OBClient_close, METH_VARARGS }, + { (char *)"OBClient_focus", _wrap_OBClient_focus, METH_VARARGS }, + { (char *)"OBClient_focusHandler", _wrap_OBClient_focusHandler, METH_VARARGS }, + { (char *)"OBClient_unfocusHandler", _wrap_OBClient_unfocusHandler, METH_VARARGS }, { (char *)"OBClient_propertyHandler", _wrap_OBClient_propertyHandler, METH_VARARGS }, { (char *)"OBClient_clientMessageHandler", _wrap_OBClient_clientMessageHandler, METH_VARARGS }, { (char *)"OBClient_shapeHandler", _wrap_OBClient_shapeHandler, METH_VARARGS }, @@ -2433,6 +2590,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"OBClient_destroyHandler", _wrap_OBClient_destroyHandler, METH_VARARGS }, { (char *)"OBClient_swigregister", OBClient_swigregister, METH_VARARGS }, { (char *)"register", _wrap_register, METH_VARARGS }, + { (char *)"preregister", _wrap_preregister, METH_VARARGS }, { (char *)"unregister", _wrap_unregister, METH_VARARGS }, { NULL, NULL } }; @@ -2465,6 +2623,7 @@ static swig_type_info _swigt__p_XConfigureRequestEvent[] = {{"_p_XConfigureReque static swig_type_info _swigt__p_otk__OtkEventHandler[] = {{"_p_otk__OtkEventHandler", 0, "otk::OtkEventHandler *", 0},{"_p_otk__OtkEventHandler"},{"_p_ob__Openbox", _p_ob__OpenboxTo_p_otk__OtkEventHandler},{"_p_ob__OBClient", _p_ob__OBClientTo_p_otk__OtkEventHandler},{0}}; static swig_type_info _swigt__p_otk__Rect[] = {{"_p_otk__Rect", 0, "otk::Rect *", 0},{"_p_otk__Rect"},{0}}; static swig_type_info _swigt__p_ob__OBWidget[] = {{"_p_ob__OBWidget", 0, "ob::OBWidget *", 0},{"_p_ob__OBWidget"},{"_p_ob__OBClient", _p_ob__OBClientTo_p_ob__OBWidget},{0}}; +static swig_type_info _swigt__p_XFocusChangeEvent[] = {{"_p_XFocusChangeEvent", 0, "XFocusChangeEvent *", 0},{"_p_XFocusChangeEvent"},{0}}; static swig_type_info _swigt__p_XClientMessageEvent[] = {{"_p_XClientMessageEvent", 0, "XClientMessageEvent *", 0},{"_p_XClientMessageEvent"},{0}}; static swig_type_info _swigt__p_otk__OBProperty[] = {{"_p_otk__OBProperty", 0, "otk::OBProperty *", 0},{"_p_otk__OBProperty"},{0}}; static swig_type_info _swigt__p_otk__OtkEventDispatcher[] = {{"_p_otk__OtkEventDispatcher", 0, "otk::OtkEventDispatcher *", 0},{"_p_otk__OtkEventDispatcher"},{"_p_ob__Openbox", _p_ob__OpenboxTo_p_otk__OtkEventDispatcher},{0}}; @@ -2490,6 +2649,7 @@ _swigt__p_XConfigureRequestEvent, _swigt__p_otk__OtkEventHandler, _swigt__p_otk__Rect, _swigt__p_ob__OBWidget, +_swigt__p_XFocusChangeEvent, _swigt__p_XClientMessageEvent, _swigt__p_otk__OBProperty, _swigt__p_otk__OtkEventDispatcher, diff --git a/src/python.cc b/src/python.cc index d44b2d48..97a3a4d2 100644 --- a/src/python.cc +++ b/src/python.cc @@ -32,6 +32,27 @@ bool python_register(int action, PyObject *callback) return true; } +bool python_preregister(int action, PyObject *callback) +{ + if (action < 0 || action >= OBActions::NUM_ACTIONS) { + PyErr_SetString(PyExc_AssertionError, "Invalid action type."); + return false; + } + if (!PyCallable_Check(callback)) { + PyErr_SetString(PyExc_AssertionError, "Invalid callback function."); + return false; + } + + FunctionList::iterator it = std::find(callbacks[action].begin(), + callbacks[action].end(), + callback); + if (it == callbacks[action].end()) { // not already in there + Py_XINCREF(callback); // Add a reference to new callback + callbacks[action].insert(callbacks[action].begin(), callback); + } + return true; +} + bool python_unregister(int action, PyObject *callback) { if (action < 0 || action >= OBActions::NUM_ACTIONS) { diff --git a/src/python.hh b/src/python.hh index 6ca4e1c5..30cd752d 100644 --- a/src/python.hh +++ b/src/python.hh @@ -15,9 +15,14 @@ extern "C" { namespace ob { +//! Add a python callback funtion to the back of the hook list bool python_register(int action, PyObject *callback); +//! Add a python callback funtion to the front of the hook list +bool python_preregister(int action, PyObject *callback); +//! Remove a python callback function from the hook list bool python_unregister(int action, PyObject *callback); +//! Fire a python callback function void python_callback(OBActions::ActionType action, Window window, OBWidget::WidgetType type, unsigned int state, long d1 = LONG_MIN, long d2 = LONG_MIN, diff --git a/src/screen.cc b/src/screen.cc index 947471c2..d61b501d 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -89,6 +89,14 @@ OBScreen::OBScreen(int screen, const otk::Configuration &config) otk::OBProperty::Atom_Cardinal, viewport, 2); + // create the window which gets focus when no clients get it + XSetWindowAttributes attr; + attr.override_redirect = true; + _focuswindow = XCreateWindow(otk::OBDisplay::display, _info->rootWindow(), + -100, -100, 1, 1, 0, 0, InputOnly, + _info->visual(), CWOverrideRedirect, &attr); + XMapWindow(otk::OBDisplay::display, _focuswindow); + // these may be further updated if any pre-existing windows are found in // the manageExising() function setClientList(); // initialize the client lists, which will be empty diff --git a/src/screen.hh b/src/screen.hh index 7e95d40f..37f22d88 100644 --- a/src/screen.hh +++ b/src/screen.hh @@ -62,6 +62,7 @@ private: //! The style with which to render on the screen otk::Style _style; + //! The screen's root window OBRootWindow _root; //! Is the root colormap currently installed? @@ -73,6 +74,9 @@ private: //! Areas of the screen reserved by applications StrutList _struts; + //! An offscreen window which gets focus when nothing else has it + Window _focuswindow; + //! Calculate the OBScreen::_area member void calcArea(); @@ -113,6 +117,8 @@ public: inline const otk::Rect &area() const { return _area; } //! Returns the style in use on the screen inline const otk::Style *style() const { return &_style; } + //! An offscreen window which gets focus when nothing else has it + inline Window focuswindow() const { return _focuswindow; } //! Adds a window's strut to the screen's list of reserved spaces void addStrut(otk::Strut *strut); |
