summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2002-12-25 22:02:34 +0000
committerDana Jansens <danakj@orodu.net>2002-12-25 22:02:34 +0000
commit2ae2b257d39ea62640c2590f794e4275c6db1cd4 (patch)
treef26abe4a0601d263fbc460eddc012c1d674c868b /src
parent3c61812e588fb3c34d0713d7f82ccbf21091f032 (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.cc58
-rw-r--r--src/backgroundwidget.hh8
-rw-r--r--src/buttonwidget.cc94
-rw-r--r--src/buttonwidget.hh13
-rw-r--r--src/client.cc36
-rw-r--r--src/client.hh7
-rw-r--r--src/frame.cc52
-rw-r--r--src/frame.hh9
-rw-r--r--src/labelwidget.cc92
-rw-r--r--src/labelwidget.hh22
-rw-r--r--src/main.cc16
-rw-r--r--src/openbox.cc25
-rw-r--r--src/openbox.hh28
-rw-r--r--src/openbox.i1
-rw-r--r--src/openbox_wrap.cc182
-rw-r--r--src/python.cc21
-rw-r--r--src/python.hh5
-rw-r--r--src/screen.cc8
-rw-r--r--src/screen.hh6
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);