all repos — openbox @ 17b0266979137ad957a701c7093a14841a8c2091

openbox fork - make it a bit more like ryudo

No longer using otk widgets for the frame decorations.
The titlebar no long has any buttons, in preparation for a new button system.
Using otk::Size for sizes, and unsigned ints (*PAIN*) we'll see..
Dana Jansens danakj@orodu.net
commit

17b0266979137ad957a701c7093a14841a8c2091

parent

1c97e9fb7bede1607b9680d29a791a72b1768019

M src/Makefile.amsrc/Makefile.am

@@ -16,11 +16,10 @@

openbox3_LDADD=-L../otk -lotk @LIBINTL@ openbox3_LDFLAGS=-export-dynamic openbox3_SOURCES= actions.cc client.cc frame.cc openbox.cc screen.cc \ - main.cc backgroundwidget.cc labelwidget.cc \ - buttonwidget.cc python.cc bindings.cc -noinst_HEADERS= actions.hh backgroundwidget.hh bindings.hh buttonwidget.hh \ - client.hh frame.hh labelwidget.hh openbox.hh python.hh \ - screen.hh widgetbase.hh gettext.h + main.cc python.cc bindings.cc +noinst_HEADERS= actions.hh bindings.hh \ + client.hh frame.hh openbox.hh python.hh \ + screen.hh MAINTAINERCLEANFILES= Makefile.in
M src/actions.ccsrc/actions.cc

@@ -5,9 +5,9 @@ # include "../config.h"

#endif #include "actions.hh" -#include "widgetbase.hh" #include "openbox.hh" #include "client.hh" +#include "frame.hh" #include "screen.hh" #include "python.hh" #include "bindings.hh"

@@ -72,12 +72,20 @@ void Actions::buttonPressHandler(const XButtonEvent &e)

{ otk::EventHandler::buttonPressHandler(e); insertPress(e); - + + MouseContext::MC context; + EventHandler *h = openbox->findHandler(e.window); + Frame *f = dynamic_cast<Frame*>(h); + if (f) + context= f->mouseContext(e.window); + else if (dynamic_cast<Client*>(h)) + context = MouseContext::Window; + else if (dynamic_cast<Screen*>(h)) + context = MouseContext::Root; + else + return; // not a valid mouse context + // run the PRESS python hook - WidgetBase *w = dynamic_cast<WidgetBase*> - (openbox->findHandler(e.window)); - if (!w) return; - // kill off the Button1Mask etc, only want the modifiers unsigned int state = e.state & (ControlMask | ShiftMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);

@@ -87,7 +95,7 @@ if (c)

screen = c->screen(); else screen = otk::display->findScreen(e.root)->screen(); - MouseData data(screen, c, e.time, state, e.button, w->mcontext(), + MouseData data(screen, c, e.time, state, e.button, context, MouseAction::Press); openbox->bindings()->fireButton(&data);

@@ -95,7 +103,7 @@ if (_button) return; // won't count toward CLICK events

_button = e.button; - if (w->mcontext() == MouseContext::Window) { + if (context == MouseContext::Window) { /* Because of how events are grabbed on the client window, we can't get ButtonRelease events, so instead we simply manufacture them here, so that

@@ -113,9 +121,17 @@ {

otk::EventHandler::buttonReleaseHandler(e); removePress(e); - WidgetBase *w = dynamic_cast<WidgetBase*> - (openbox->findHandler(e.window)); - if (!w) return; + MouseContext::MC context; + EventHandler *h = openbox->findHandler(e.window); + Frame *f = dynamic_cast<Frame*>(h); + if (f) + context= f->mouseContext(e.window); + else if (dynamic_cast<Client*>(h)) + context = MouseContext::Window; + else if (dynamic_cast<Screen*>(h)) + context = MouseContext::Root; + else + return; // not a valid mouse context // run the RELEASE python hook // kill off the Button1Mask etc, only want the modifiers

@@ -127,7 +143,7 @@ if (c)

screen = c->screen(); else screen = otk::display->findScreen(e.root)->screen(); - MouseData data(screen, c, e.time, state, e.button, w->mcontext(), + MouseData data(screen, c, e.time, state, e.button, context, MouseAction::Release); openbox->bindings()->fireButton(&data);

@@ -260,6 +276,18 @@ otk::EventHandler::motionHandler(e);

if (!e.same_screen) return; // this just gets stupid + MouseContext::MC context; + EventHandler *h = openbox->findHandler(e.window); + Frame *f = dynamic_cast<Frame*>(h); + if (f) + context= f->mouseContext(e.window); + else if (dynamic_cast<Client*>(h)) + context = MouseContext::Window; + else if (dynamic_cast<Screen*>(h)) + context = MouseContext::Root; + else + return; // not a valid mouse context + int x_root = e.x_root, y_root = e.y_root; // compress changes to a window into a single change

@@ -268,10 +296,6 @@ while (XCheckTypedWindowEvent(**otk::display, e.window, e.type, &ce)) {

x_root = e.x_root; y_root = e.y_root; } - - WidgetBase *w = dynamic_cast<WidgetBase*> - (openbox->findHandler(e.window)); - if (!w) return; if (!_dragging) { long threshold;

@@ -298,7 +322,7 @@ if (c)

screen = c->screen(); else screen = otk::display->findScreen(e.root)->screen(); - MouseData data(screen, c, e.time, state, button, w->mcontext(), + MouseData data(screen, c, e.time, state, button, context, MouseAction::Motion, x_root, y_root, _posqueue[0]->pos, _posqueue[0]->clientarea); openbox->bindings()->fireButton(&data);
D src/backgroundwidget.cc

@@ -1,87 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "backgroundwidget.hh" - -namespace ob { - -BackgroundWidget::BackgroundWidget(otk::Widget *parent, - WidgetBase::WidgetType type) - : otk::Widget(parent), - WidgetBase(type) -{ -} - - -BackgroundWidget::~BackgroundWidget() -{ -} - - -void BackgroundWidget::setTextures() -{ - switch (type()) { - case Type_Titlebar: - if (_focused) - setTexture(_style->titlebarFocusBackground()); - else - setTexture(_style->titlebarUnfocusBackground()); - break; - case Type_Handle: - if (_focused) - setTexture(_style->handleFocusBackground()); - else - setTexture(_style->handleUnfocusBackground()); - break; - case Type_Plate: - if (_focused) - setBorderColor(_style->clientBorderFocusColor()); - else - setBorderColor(_style->clientBorderUnfocusColor()); - break; - default: - assert(false); // there's no other background widgets! - } -} - - -void BackgroundWidget::setStyle(otk::RenderStyle *style) -{ - Widget::setStyle(style); - setTextures(); - switch (type()) { - case Type_Titlebar: - case Type_Handle: - setBorderColor(_style->frameBorderColor()); - break; - case Type_Plate: - break; - default: - assert(false); // there's no other background widgets! - } -} - - -void BackgroundWidget::focus() -{ - otk::Widget::focus(); - setTextures(); -} - - -void BackgroundWidget::unfocus() -{ - otk::Widget::unfocus(); - setTextures(); -} - - -void BackgroundWidget::adjust() -{ - // nothing to adjust here. its done in Frame::adjustSize -} - -}
D src/backgroundwidget.hh

@@ -1,29 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __backgroundwidget_hh -#define __backgroundwidget_hh - -#include "otk/widget.hh" -#include "widgetbase.hh" - -namespace ob { - -class BackgroundWidget : public otk::Widget, public WidgetBase -{ -private: - void setTextures(); - -public: - BackgroundWidget(otk::Widget *parent, WidgetBase::WidgetType type); - virtual ~BackgroundWidget(); - - virtual void setStyle(otk::RenderStyle *style); - - virtual void adjust(); - - virtual void focus(); - virtual void unfocus(); -}; - -} - -#endif // __backgroundwidget_hh
D src/buttonwidget.cc

@@ -1,215 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "buttonwidget.hh" -#include "client.hh" - -namespace ob { - -ButtonWidget::ButtonWidget(otk::Widget *parent, - WidgetBase::WidgetType type, - Client *client) - : otk::Widget(parent), - WidgetBase(type), - _client(client), - _pressed(false), - _button(0), - _state(false) -{ -} - - -ButtonWidget::~ButtonWidget() -{ -} - - -void ButtonWidget::setTextures() -{ - bool p = _pressed; - - switch (type()) { - case Type_AllDesktopsButton: - if (_client->desktop() == (signed)0xffffffff) - p = true; - break; - case Type_MaximizeButton: - if (_client->maxHorz() || _client->maxVert()) - p = true; - break; - default: - break; - } - - switch (type()) { - case Type_LeftGrip: - case Type_RightGrip: - if (_focused) - setTexture(_style->gripFocusBackground()); - else - setTexture(_style->gripUnfocusBackground()); - break; - case Type_AllDesktopsButton: - case Type_MaximizeButton: - case Type_CloseButton: - case Type_IconifyButton: - if (p) { - if (_focused) - setTexture(_style->buttonPressFocusBackground()); - else - setTexture(_style->buttonPressUnfocusBackground()); - } else { - if (_focused) - setTexture(_style->buttonUnpressFocusBackground()); - else - setTexture(_style->buttonUnpressUnfocusBackground()); - } - break; - default: - assert(false); // there's no other button widgets! - } -} - - -void ButtonWidget::setStyle(otk::RenderStyle *style) -{ - otk::Widget::setStyle(style); - setTextures(); - - switch (type()) { - case Type_LeftGrip: - case Type_RightGrip: - setBorderColor(_style->frameBorderColor()); - break; - case Type_AllDesktopsButton: - case Type_CloseButton: - case Type_MaximizeButton: - case Type_IconifyButton: - break; - default: - assert(false); // there's no other button widgets! - } -} - - -void ButtonWidget::update() -{ - switch (type()) { - case Type_AllDesktopsButton: - if ((_client->desktop() == (signed)0xffffffff) != _state) { - _state = !_state; - setTextures(); - } - break; - case Type_MaximizeButton: - if ((_client->maxHorz() || _client->maxVert()) != _state) { - _state = !_state; - setTextures(); - } - break; - default: - break; - } - - otk::Widget::update(); -} - - -void ButtonWidget::renderForeground() -{ - otk::PixmapMask *pm; - int width; - bool draw = _dirty; - - otk::Widget::renderForeground(); - - if (draw) { - switch (type()) { - case Type_AllDesktopsButton: - pm = _style->alldesktopsMask(); - break; - case Type_CloseButton: - pm = _style->closeMask(); - break; - case Type_MaximizeButton: - pm = _style->maximizeMask(); - break; - case Type_IconifyButton: - pm = _style->iconifyMask(); - break; - case Type_LeftGrip: - case Type_RightGrip: - return; // no drawing - default: - assert(false); // there's no other button widgets! - } - - assert(pm->mask); - if (pm->mask == None) return; // no mask for the button, leave it empty - - width = _rect.width(); - - otk::RenderColor *color = (_focused ? _style->buttonFocusColor() : - _style->buttonUnfocusColor()); - - // set the clip region - int x = (width - pm->w) / 2, y = (width - pm->h) / 2; - XSetClipMask(**otk::display, color->gc(), pm->mask); - XSetClipOrigin(**otk::display, color->gc(), x, y); - - // fill in the clipped region - XFillRectangle(**otk::display, _surface->pixmap(), color->gc(), x, y, - x + pm->w, y + pm->h); - - // unset the clip region - XSetClipMask(**otk::display, color->gc(), None); - XSetClipOrigin(**otk::display, color->gc(), 0, 0); - } -} - - -void ButtonWidget::adjust() -{ - // nothing to adjust. no children. -} - - -void ButtonWidget::focus() -{ - otk::Widget::focus(); - setTextures(); -} - - -void ButtonWidget::unfocus() -{ - otk::Widget::unfocus(); - setTextures(); -} - - -void ButtonWidget::buttonPressHandler(const XButtonEvent &e) -{ - otk::Widget::buttonPressHandler(e); - if (_button) return; - _button = e.button; - _pressed = true; - setTextures(); - update(); -} - - -void ButtonWidget::buttonReleaseHandler(const XButtonEvent &e) -{ - otk::Widget::buttonPressHandler(e); - if (e.button != _button) return; - _button = 0; - _pressed = false; - setTextures(); - update(); -} - -}
D src/buttonwidget.hh

@@ -1,43 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __buttonwidget_hh -#define __buttonwidget_hh - -#include "widgetbase.hh" -#include "otk/widget.hh" - -namespace ob { - -class Client; - -class ButtonWidget : public otk::Widget, public WidgetBase -{ -private: - void setTextures(); - Client *_client; - bool _pressed; - unsigned int _button; - bool _state; - -public: - ButtonWidget(otk::Widget *parent, WidgetBase::WidgetType type, - Client *client); - virtual ~ButtonWidget(); - - virtual void setStyle(otk::RenderStyle *style); - - virtual void adjust(); - - virtual void update(); - - virtual void renderForeground(); - - virtual void focus(); - virtual void unfocus(); - - virtual void buttonPressHandler(const XButtonEvent &e); - virtual void buttonReleaseHandler(const XButtonEvent &e); -}; - -} - -#endif // __buttonwidget_hh
M src/client.ccsrc/client.cc

@@ -29,7 +29,6 @@ namespace ob {

Client::Client(int screen, Window window) : otk::EventHandler(), - WidgetBase(WidgetBase::Type_Client), frame(0), _screen(screen), _window(window) { assert(screen >= 0);

@@ -581,7 +580,7 @@ if (_title.empty())

_title = _("Unnamed Window"); if (frame) - frame->setTitle(_title); + frame->adjustTitle(); }

@@ -1128,8 +1127,14 @@

void Client::internal_resize(Corner anchor, unsigned int w, unsigned int h, bool user, int x, int y) { - w -= _base_size.width(); - h -= _base_size.height(); + if (_base_size.width() < w) + w -= _base_size.width(); + else + w = 0; + if (_base_size.height() < h) + h -= _base_size.height(); + else + h = 0; if (user) { // for interactive resizing. have to move half an increment in each

@@ -1714,8 +1719,8 @@ #endif // DEBUG

otk::EventHandler::focusHandler(e); - frame->focus(); _focused = true; + frame->adjustFocus(); openbox->setFocusedClient(this); }

@@ -1729,26 +1734,29 @@ #endif // DEBUG

otk::EventHandler::unfocusHandler(e); - frame->unfocus(); _focused = false; + frame->adjustFocus(); if (openbox->focusedClient() == this) openbox->setFocusedClient(0); } -void Client::configureRequestHandler(const XConfigureRequestEvent &e) +void Client::configureRequestHandler(const XConfigureRequestEvent &ec) { #ifdef DEBUG - printf("ConfigureRequest for 0x%lx\n", e.window); + printf("ConfigureRequest for 0x%lx\n", ec.window); #endif // DEBUG - otk::EventHandler::configureRequestHandler(e); + otk::EventHandler::configureRequestHandler(ec); // compress these + XConfigureRequestEvent e = ec; XEvent ev; while (XCheckTypedWindowEvent(**otk::display, window(), ConfigureRequest, &ev)) { + // XXX if this causes bad things.. we can compress config req's with the + // same mask. e.value_mask |= ev.xconfigurerequest.value_mask; if (ev.xconfigurerequest.value_mask & CWX) e.x = ev.xconfigurerequest.x;
M src/client.hhsrc/client.hh

@@ -8,8 +8,6 @@ property changes on the window and some client messages

*/ #include "screen.hh" -#include "widgetbase.hh" -#include "otk/point.hh" #include "otk/strut.hh" #include "otk/rect.hh" #include "otk/eventhandler.hh"

@@ -56,7 +54,7 @@ client, it will call the ActionHandler (for client messages) or update the

class' member variables and call whatever is nessary to complete the change (such as causing a redraw of the titlebar after the title is changed). */ -class Client : public otk::EventHandler, public WidgetBase { +class Client : public otk::EventHandler { public: //! The frame window which decorates around the client window

@@ -229,7 +227,7 @@ size of the window, and is the value that should be displayed to the user.

For example, with xterms, this value it the number of characters being displayed in the terminal, instead of the number of pixels. */ - otk::Point _logical_size; + otk::Size _logical_size; //! Width of the border on the window. /*!

@@ -253,20 +251,20 @@ //! The minimum size of the client window

/*! If the min is > the max, then the window is not resizable */ - otk::Point _min_size; + otk::Size _min_size; //! The maximum size of the client window /*! If the min is > the max, then the window is not resizable */ - otk::Point _max_size; + otk::Size _max_size; //! The size of increments to resize the client window by - otk::Point _size_inc; + otk::Size _size_inc; //! The base size of the client window /*! This value should be subtracted from the window's actual size when displaying its size to the user, or working with its min/max size */ - otk::Point _base_size; + otk::Size _base_size; //! Window decoration and functionality hints MwmHints _mwmhints;

@@ -481,8 +479,8 @@ after resizing.

The x and y coordinates must both be sepcified together, or they will have no effect. When they are specified, the anchor is ignored. */ - void internal_resize(Corner anchor, int w, int h, bool user = true, - int x = INT_MIN, int y = INT_MIN); + void internal_resize(Corner anchor, unsigned int w, unsigned int h, + bool user = true, int x = INT_MIN, int y = INT_MIN); //! Attempts to find and return a modal child of this window, recursively. Client *findModalChild(Client *skip = 0) const;

@@ -629,7 +627,7 @@ size of the window, and is the value that should be displayed to the user.

For example, with xterms, this value it the number of characters being displayed in the terminal, instead of the number of pixels. */ - const otk::Point &logicalSize() const { return _logical_size; } + const otk::Size &logicalSize() const { return _logical_size; } //! Returns the position and size of the client relative to the root window inline const otk::Rect &area() const { return _area; }

@@ -653,7 +651,7 @@ @param anchor The corner to keep in the same position when resizing.

@param w The width component of the new size for the client. @param h The height component of the new size for the client. */ - void resize(Corner anchor, int w, int h); + void resize(Corner anchor, unsigned int w, unsigned int h); //! Reapplies the maximized state to the window /*!
M src/frame.ccsrc/frame.cc

@@ -10,336 +10,387 @@ #include <X11/extensions/shape.h>

#endif // SHAPE } -#include "openbox.hh" #include "frame.hh" #include "client.hh" -#include "python.hh" -#include "bindings.hh" +#include "openbox.hh" #include "otk/display.hh" #include <string> +#include <cassert> namespace ob { const long Frame::event_mask; -Frame::Frame(Client *client, otk::RenderStyle *style) - : otk::Widget(openbox, style, Horizontal, 0, 1, true), - WidgetBase(WidgetBase::Type_Frame), - _client(client), - _screen(otk::display->screenInfo(client->screen())), - _plate(this, WidgetBase::Type_Plate), - _titlebar(this, WidgetBase::Type_Titlebar), - _button_close(&_titlebar, WidgetBase::Type_CloseButton, client), - _button_iconify(&_titlebar, WidgetBase::Type_IconifyButton, client), - _button_max(&_titlebar, WidgetBase::Type_MaximizeButton, client), - _button_alldesk(&_titlebar, WidgetBase::Type_AllDesktopsButton, client), - _label(&_titlebar, WidgetBase::Type_Label), - _handle(this, WidgetBase::Type_Handle), - _grip_left(&_handle, WidgetBase::Type_LeftGrip, client), - _grip_right(&_handle, WidgetBase::Type_RightGrip, client), - _decorations(client->decorations()) +Window createWindow(const otk::ScreenInfo *info, Window parent, + unsigned long mask, XSetWindowAttributes *attrib) +{ + return XCreateWindow(**otk::display, parent, 0, 0, 1, 1, 0, + info->depth(), InputOutput, info->visual(), + mask, attrib); + +} + +Frame::Frame(Client *client) + : _client(client), + _visible(false), + _plate(0), + _title(0), + _label(0), + _handle(0), + _lgrip(0), + _rgrip(0), + _buttons(0), + _numbuttons(0), + _titleorder(0), + _frame_sur(0), + _title_sur(0), + _label_sur(0), + _handle_sur(0), + _grip_sur(0), + _buttons_sur(0) { assert(client); - assert(style); + + XSetWindowAttributes attrib; + unsigned long mask; + const otk::ScreenInfo *info = otk::display->screenInfo(client->screen()); + + // create all of the decor windows (except title bar buttons) + mask = CWOverrideRedirect | CWEventMask; + attrib.event_mask = Frame::event_mask; + attrib.override_redirect = true; + _frame = createWindow(info, info->rootWindow(), mask, &attrib); + + mask = 0; + _plate = createWindow(info, _frame, mask, &attrib); + mask = CWEventMask; + attrib.event_mask = (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | + ExposureMask); + _title = createWindow(info, _frame, mask, &attrib); + _label = createWindow(info, _title, mask, &attrib); + _handle = createWindow(info, _frame, mask, &attrib); + mask |= CWCursor; + attrib.cursor = openbox->cursors().ll_angle; + _lgrip = createWindow(info, _handle, mask, &attrib); + attrib.cursor = openbox->cursors().lr_angle; + _rgrip = createWindow(info, _handle, mask, &attrib); - XSelectInput(**otk::display, _window, Frame::event_mask); + // the other stuff is shown based on decor settings + XMapWindow(**otk::display, _plate); + XMapWindow(**otk::display, _lgrip); + XMapWindow(**otk::display, _rgrip); + XMapWindow(**otk::display, _label); - _grip_left.setCursor(openbox->cursors().ll_angle); - _grip_right.setCursor(openbox->cursors().lr_angle); - - _label.setText(_client->title()); + applyStyle(*otk::RenderStyle::style(_client->screen())); - _style = 0; - setStyle(style); + // XXX load buttons + _numbuttons = 0; + _buttons = new Window[0]; + _buttons_sur = new otk::Surface*[0]; + _titleorder = new unsigned int[1]; + _titleorder[0] = (unsigned)-1; - otk::Widget::unfocus(); // stuff starts out appearing focused in otk - - _plate.show(); // the other stuff is shown based on decor settings + // register all of the windows with the event dispatcher + Window *w = allWindows(); + for (unsigned int i = 0; w[i]; ++i) + openbox->registerHandler(w[i], this); + delete [] w; } - Frame::~Frame() { + // unregister all of the windows with the event dispatcher + Window *w = allWindows(); + for (unsigned int i = 0; w[i]; ++i) + openbox->clearHandler(w[i]); + delete [] w; + + for (unsigned int i = 0; i < _numbuttons; ++i) { + XDestroyWindow(**otk::display, _buttons[i]); + delete _buttons_sur[i]; + } + XDestroyWindow(**otk::display, _rgrip); + XDestroyWindow(**otk::display, _lgrip); + XDestroyWindow(**otk::display, _handle); + XDestroyWindow(**otk::display, _label); + XDestroyWindow(**otk::display, _title); + XDestroyWindow(**otk::display, _frame); + + if (_frame_sur) delete _frame_sur; + if (_title_sur) delete _title_sur; + if (_label_sur) delete _label_sur; + if (_handle_sur) delete _handle_sur; + if (_grip_sur) delete _grip_sur; + + delete [] _buttons; + delete [] _titleorder; + delete [] _buttons_sur; } +void Frame::show() +{ + if (!_visible) { + _visible = true; + XMapWindow(**otk::display, _frame); + } +} -void Frame::setTitle(const otk::ustring &text) +void Frame::hide() { - _label.setText(text); - _label.update(); + if (_visible) { + _visible = false; + XUnmapWindow(**otk::display, _frame); + } } +MouseContext::MC Frame::mouseContext(Window win) const +{ + if (win == _frame) return MouseContext::Frame; + if (win == _title || + win == _label) return MouseContext::Titlebar; + if (win == _handle) return MouseContext::Handle; + if (win == _plate) return MouseContext::Window; + if (win == _lgrip || + win == _rgrip) return MouseContext::Grip; + return (MouseContext::MC) -1; +} -void Frame::setStyle(otk::RenderStyle *style) +Window *Frame::allWindows() const { - assert(style); + Window *w = new Window[7 + _numbuttons + 1]; + unsigned int i = 0; + w[i++] = _frame; + w[i++] = _plate; + w[i++] = _title; + w[i++] = _label; + w[i++] = _handle; + w[i++] = _lgrip; + w[i++] = _rgrip; + for (unsigned int j = 0; j < _numbuttons; ++j) + w[j + i++] = _buttons[j]; + w[i] = 0; + return w; +} - // if a style was previously set, then 'replace' is true, cause we're - // replacing a style - bool replace = (_style); +void Frame::applyStyle(const otk::RenderStyle &style) +{ + // set static border colors + XSetWindowBorder(**otk::display, _frame, style.frameBorderColor()->pixel()); + XSetWindowBorder(**otk::display, _title, style.frameBorderColor()->pixel()); + XSetWindowBorder(**otk::display, _handle, style.frameBorderColor()->pixel()); + XSetWindowBorder(**otk::display, _lgrip, style.frameBorderColor()->pixel()); + XSetWindowBorder(**otk::display, _rgrip, style.frameBorderColor()->pixel()); - otk::Widget::setStyle(style); - - if (replace) { - // XXX: do shit here whatever - } + // size all the fixed-size elements + geom.font_height = style.labelFont()->height(); + if (geom.font_height < 1) geom.font_height = 1; + geom.button_size = geom.font_height - 2; + if (geom.button_size < 1) geom.button_size = 1; + geom.handle_height = style.handleWidth(); + if (geom.handle_height < 1) geom.handle_height = 1; + geom.bevel = style.bevelWidth(); + + XResizeWindow(**otk::display, _lgrip, geom.grip_width(), geom.handle_height); + XResizeWindow(**otk::display, _rgrip, geom.grip_width(), geom.handle_height); - _style = style; - - setBorderColor(_style->frameBorderColor()); - - // if !replace, then adjust() will get called after the client is grabbed! - if (replace) { - // size/position everything - adjustSize(); - adjustPosition(); - } + for (unsigned int i = 0; i < _numbuttons; ++i) + XResizeWindow(**otk::display, _buttons[i], + geom.button_size, geom.button_size); } - -void Frame::focus() +void Frame::styleChanged(const otk::RenderStyle &style) { - otk::Widget::focus(); - update(); + applyStyle(style); + + // size/position everything + adjustSize(); + adjustPosition(); } - -void Frame::unfocus() +void Frame::adjustFocus() { - otk::Widget::unfocus(); - update(); + // XXX optimizations later... + adjustSize(); } - -void Frame::adjust() +void Frame::adjustTitle() { - // the party all happens in adjustSize + // XXX optimizations later... + adjustSize(); } +static void render(int screen, const otk::Size &size, Window win, + otk::Surface **surface, + const otk::RenderTexture &texture) +{ + otk::Surface *s = new otk::Surface(screen, size); + otk::display->renderControl(screen)->drawBackground(*s, texture); + XSetWindowBackgroundPixmap(**otk::display, win, s->pixmap()); + XClearWindow(**otk::display, win); + if (*surface) delete *surface; + *surface = s; +} void Frame::adjustSize() { - // XXX: only if not overridden or something!!! MORE LOGIC HERE!! - _decorations = _client->decorations(); + Client::DecorationFlags decorations = _client->decorations(); + const otk::RenderStyle *style = otk::RenderStyle::style(_client->screen()); + + if (decorations & Client::Decor_Border) { + geom.bwidth = style->frameBorderWidth(); + geom.cbwidth = style->clientBorderWidth(); + } else { + geom.bwidth = geom.cbwidth = 0; + } + _innersize.left = _innersize.top = _innersize.bottom = _innersize.right = + geom.cbwidth; + geom.width = _client->area().width() + geom.cbwidth * 2; + assert(geom.width > 0); - // true/false for whether to show each element of the titlebar - bool tit_i = false, tit_m = false, tit_s = false, tit_c = false; - int width; // the width of the client and its border - int bwidth; // width to make borders - int cbwidth; // width of the inner client border - int fontheight = _style->labelFont()->height(); // height of the font - int butsize = fontheight - 2; // width and height of the titlebar buttons - const int bevel = _style->bevelWidth(); + // set border widths + XSetWindowBorderWidth(**otk::display, _plate, geom.cbwidth); + XSetWindowBorderWidth(**otk::display, _frame, geom.bwidth); + XSetWindowBorderWidth(**otk::display, _title, geom.bwidth); + XSetWindowBorderWidth(**otk::display, _handle, geom.bwidth); + XSetWindowBorderWidth(**otk::display, _lgrip, geom.bwidth); + XSetWindowBorderWidth(**otk::display, _rgrip, geom.bwidth); - if (_decorations & Client::Decor_Border) { - bwidth = _style->frameBorderWidth(); - cbwidth = _style->clientBorderWidth(); - } else - bwidth = cbwidth = 0; - _innersize.left = _innersize.top = _innersize.bottom = _innersize.right = - cbwidth; - width = _client->area().width() + cbwidth * 2; + // position/size and map/unmap all the windows - _plate.setBorderWidth(cbwidth); + if (decorations & Client::Decor_Titlebar) { + XMoveResizeWindow(**otk::display, _title, -geom.bwidth, -geom.bwidth, + geom.width, geom.title_height()); + _innersize.top += geom.title_height() + geom.bwidth; + XMapWindow(**otk::display, _title); - setBorderWidth(bwidth); - _titlebar.setBorderWidth(bwidth); - _grip_left.setBorderWidth(bwidth); - _grip_right.setBorderWidth(bwidth); - _handle.setBorderWidth(bwidth); + // layout the title bar elements + layoutTitle(); + } else + XUnmapWindow(**otk::display, _title); + + if (decorations & Client::Decor_Handle) { + geom.handle_y = _innersize.top + _client->area().height() + geom.cbwidth; + XMoveResizeWindow(**otk::display, _handle, -geom.bwidth, geom.handle_y, + geom.width, geom.handle_height); + XMoveWindow(**otk::display, _lgrip, -geom.bwidth, -geom.bwidth); + XMoveWindow(**otk::display, _rgrip, + -geom.bwidth + geom.width - geom.grip_width(), + -geom.bwidth); + _innersize.bottom += geom.handle_height + geom.bwidth; + XMapWindow(**otk::display, _handle); + } else + XUnmapWindow(**otk::display, _handle); - if (_decorations & Client::Decor_Titlebar) { - // set the titlebar size - _titlebar.setGeometry(-bwidth, - -bwidth, - width, - _style->labelFont()->height() + (bevel * 2)); - _innersize.top += _titlebar.height() + bwidth; + XResizeWindow(**otk::display, _frame, geom.width, + (_client->shaded() ? geom.title_height() : + _innersize.top + _innersize.bottom + + _client->area().height())); - // set the label size - _label.setGeometry(0, bevel, width, fontheight); - // set the buttons sizes - if (_decorations & Client::Decor_Iconify) - _button_iconify.setGeometry(0, bevel + 1, butsize, butsize); - if (_decorations & Client::Decor_Maximize) - _button_max.setGeometry(0, bevel + 1, butsize, butsize); - if (_decorations & Client::Decor_AllDesktops) - _button_alldesk.setGeometry(0, bevel + 1, butsize, butsize); - if (_decorations & Client::Decor_Close) - _button_close.setGeometry(0, bevel + 1, butsize, butsize); + XMoveResizeWindow(**otk::display, _plate, + _innersize.left - geom.cbwidth, + _innersize.top - geom.cbwidth, + _client->area().width(), _client->area().height()); - // separation between titlebar elements - const int sep = bevel + 1; + _size.left = _innersize.left + geom.bwidth; + _size.right = _innersize.right + geom.bwidth; + _size.top = _innersize.top + geom.bwidth; + _size.bottom = _innersize.bottom + geom.bwidth; - otk::ustring layout; - if (!python_get_string("TITLEBAR_LAYOUT", &layout)) - layout = "ILMC"; + _area = otk::Rect(_area.position(), otk::Size(_client->area().width() + + _size.left + _size.right, + _client->area().height() + + _size.top + _size.bottom)); - // this code ensures that the string only has one of each possible - // letter, all of the letters are valid, and L exists somewhere in the - // string! - bool tit_l = false; - - for (std::string::size_type i = 0; i < layout.size(); ++i) { - switch (layout[i]) { - case 'i': - case 'I': - if (!tit_i && (_decorations & Client::Decor_Iconify)) { - tit_i = true; - continue; - } - break; - case 'l': - case 'L': - if (!tit_l) { - tit_l = true; - continue; - } - break; - case 'm': - case 'M': - if (!tit_m && (_decorations & Client::Decor_Maximize)) { - tit_m = true; - continue; - } - break; - case 'd': - case 'D': - if (!tit_s && (_decorations & Client::Decor_AllDesktops)) { - tit_s = true; - continue; - } - break; - case 'c': - case 'C': - if (!tit_c && (_decorations & Client::Decor_Close)) { - tit_c = true; - continue; - } - break; - } - // if we get here then we don't want the letter, kill it - layout.erase(i--, 1); - } - if (!tit_l) - layout += "L"; + // render all the elements + int screen = _client->screen(); + bool focus = _client->focused(); + if (decorations & Client::Decor_Titlebar) { + render(screen, otk::Size(geom.width, geom.title_height()), _title, + &_title_sur, *(focus ? style->titlebarFocusBackground() : + style->titlebarUnfocusBackground())); - // the size of the label. this ASSUMES the layout has only buttons other - // that the ONE LABEL!! - // adds an extra sep so that there's a space on either side of the - // titlebar.. note: x = sep, below. - int lwidth = width - sep * 2 - - (butsize + sep) * (layout.size() - 1); - // quick sanity check for really small windows. if this is needed, its - // obviously not going to be displayed right... - // XXX: maybe we should make this look better somehow? constraints? - if (lwidth <= 0) lwidth = 1; - _label.setWidth(lwidth); - - int x = sep; - for (std::string::size_type i = 0, len = layout.size(); i < len; ++i) { - switch (layout[i]) { - case 'i': - case 'I': - _button_iconify.move(x, _button_iconify.rect().y()); - x += _button_iconify.width(); - break; - case 'l': - case 'L': - _label.move(x, _label.rect().y()); - x += _label.width(); - break; - case 'm': - case 'M': - _button_max.move(x, _button_max.rect().y()); - x += _button_max.width(); - break; - case 'd': - case 'D': - _button_alldesk.move(x, _button_alldesk.rect().y()); - x += _button_alldesk.width(); - break; - case 'c': - case 'C': - _button_close.move(x, _button_close.rect().y()); - x += _button_close.width(); - break; - default: - assert(false); // the layout string is invalid! - } - x += sep; - } + renderLabel(); } - if (_decorations & Client::Decor_Handle) { - _handle.setGeometry(-bwidth, - _innersize.top + _client->area().height() + cbwidth, - width, _style->handleWidth()); - _grip_left.setGeometry(-bwidth, - -bwidth, - butsize * 2, - _handle.height()); - _grip_right.setGeometry(((_handle.rect().right() + 1) - - butsize * 2), - -bwidth, - butsize * 2, - _handle.height()); - _innersize.bottom += _handle.height() + bwidth; + if (decorations & Client::Decor_Handle) { + render(screen, otk::Size(geom.width, geom.handle_height), _handle, + &_handle_sur, *(focus ? style->handleFocusBackground() : + style->handleUnfocusBackground())); + render(screen, otk::Size(geom.grip_width(), geom.handle_height), _lgrip, + &_grip_sur, *(focus ? style->gripFocusBackground() : + style->gripUnfocusBackground())); + XSetWindowBackgroundPixmap(**otk::display, _rgrip, _grip_sur->pixmap()); + XClearWindow(**otk::display, _rgrip); } + + XSetWindowBorder(**otk::display, _plate, + focus ? style->clientBorderFocusColor()->pixel() : + style->clientBorderUnfocusColor()->pixel()); + adjustShape(); +} - // position/size all the windows +void Frame::renderLabel() +{ + const otk::RenderStyle *style = otk::RenderStyle::style(_client->screen()); + const otk::RenderControl *control = + otk::display->renderControl(_client->screen()); + const otk::Font *font = style->labelFont(); - if (_client->shaded()) - resize(_innersize.left + _innersize.right + _client->area().width(), - _titlebar.height()); - else - resize(_innersize.left + _innersize.right + _client->area().width(), - _innersize.top + _innersize.bottom + _client->area().height()); + otk::Surface *s = new otk::Surface(_client->screen(), + otk::Size(geom.label_width, + geom.label_height())); + control->drawBackground(*s, *(_client->focused() ? + style->labelFocusBackground() : + style->labelUnfocusBackground())); - _plate.setGeometry(_innersize.left - cbwidth, _innersize.top - cbwidth, - _client->area().width(), _client->area().height()); + otk::ustring t = _client->title(); // the actual text to draw + int x = geom.bevel; // x coord for the text - // map/unmap all the windows - if (_decorations & Client::Decor_Titlebar) { - _label.show(); - if (tit_i) - _button_iconify.show(); - else - _button_iconify.hide(); - if (tit_m) - _button_max.show(); - else - _button_max.hide(); - if (tit_s) - _button_alldesk.show(); - else - _button_alldesk.hide(); - if (tit_c) - _button_close.show(); - else - _button_close.hide(); - _titlebar.show(); - } else { - _titlebar.hide(true); - } + if ((unsigned)x * 2 > geom.label_width) return; // no room at all - if (_decorations & Client::Decor_Handle) - _handle.show(true); - else - _handle.hide(true); - - _size.left = _innersize.left + bwidth; - _size.right = _innersize.right + bwidth; - _size.top = _innersize.top + bwidth; - _size.bottom = _innersize.bottom + bwidth; + // find a string that will fit inside the area for text + otk::ustring::size_type text_len = t.size(); + unsigned int length; + unsigned int maxsize = geom.label_width - geom.bevel * 2; + + do { + t.resize(text_len); + length = font->measureString(t); + } while (length > maxsize && text_len-- > 0); - adjustShape(); + if (text_len <= 0) return; // won't fit anything + + // justify the text + switch (style->labelTextJustify()) { + case otk::RenderStyle::RightBottomJustify: + x += maxsize - length; + break; + case otk::RenderStyle::CenterJustify: + x += (maxsize - length) / 2; + break; + case otk::RenderStyle::LeftTopJustify: + break; + } + + control->drawString(*s, *font, x, 0, + *(_client->focused() ? style->textFocusColor() : + style->textUnfocusColor()), t); - update(); + XSetWindowBackgroundPixmap(**otk::display, _label, s->pixmap()); + XClearWindow(**otk::display, _label); + if (_label_sur) delete _label_sur; + _label_sur = s; } +void Frame::layoutTitle() +{ + geom.label_width = geom.width - geom.bevel * 2; + if (geom.label_width < 1) geom.label_width = 1; + XMoveResizeWindow(**otk::display, _label, geom.bevel, geom.bevel, + geom.label_width, geom.font_height); +} void Frame::adjustPosition() {

@@ -347,25 +398,25 @@ int x, y;

x = _client->area().x(); y = _client->area().y(); clientGravity(x, y); - move(x, y); + XMoveWindow(**otk::display, _frame, x, y); + _area = otk::Rect(otk::Point(x, y), _area.size()); } void Frame::adjustShape() { #ifdef SHAPE - int bwidth = (_decorations & Client::Decor_Border) ? - _style->frameBorderWidth() : 0; + Client::DecorationFlags decorations = _client->decorations(); if (!_client->shaped()) { // clear the shape on the frame window - XShapeCombineMask(**otk::display, _window, ShapeBounding, + XShapeCombineMask(**otk::display, _frame, ShapeBounding, _innersize.left, _innersize.top, None, ShapeSet); } else { // make the frame's shape match the clients - XShapeCombineShape(**otk::display, _window, ShapeBounding, + XShapeCombineShape(**otk::display, _frame, ShapeBounding, _innersize.left, _innersize.top, _client->window(), ShapeBounding, ShapeSet);

@@ -373,23 +424,23 @@

int num = 0; XRectangle xrect[2]; - if (_decorations & Client::Decor_Titlebar) { - xrect[0].x = _titlebar.rect().x(); - xrect[0].y = _titlebar.rect().y(); - xrect[0].width = _titlebar.width() + bwidth * 2; // XXX: this is useless once the widget handles borders! - xrect[0].height = _titlebar.height() + bwidth * 2; + if (decorations & Client::Decor_Titlebar) { + xrect[0].x = -geom.bevel; + xrect[0].y = -geom.bevel; + xrect[0].width = geom.width + geom.bwidth * 2; + xrect[0].height = geom.title_height() + geom.bwidth * 2; ++num; } - if (_decorations & Client::Decor_Handle) { - xrect[1].x = _handle.rect().x(); - xrect[1].y = _handle.rect().y(); - xrect[1].width = _handle.width() + bwidth * 2; // XXX: this is useless once the widget handles borders! - xrect[1].height = _handle.height() + bwidth * 2; + if (decorations & Client::Decor_Handle) { + xrect[1].x = -geom.bevel; + xrect[1].y = geom.handle_y; + xrect[1].width = geom.width + geom.bwidth * 2; + xrect[1].height = geom.handle_height + geom.bwidth * 2; ++num; } - XShapeCombineRectangles(**otk::display, window(), + XShapeCombineRectangles(**otk::display, _frame, ShapeBounding, 0, 0, xrect, num, ShapeUnion, Unsorted); }

@@ -399,15 +450,15 @@

void Frame::adjustState() { - _button_alldesk.update(); - _button_max.update(); +// XXX _button_alldesk.update(); +// XXX _button_max.update(); } void Frame::grabClient() { // reparent the client to the frame - XReparentWindow(**otk::display, _client->window(), _plate.window(), 0, 0); + XReparentWindow(**otk::display, _client->window(), _plate, 0, 0); /* When reparenting the client window, it is usually not mapped yet, since this occurs from a MapRequest. However, in the case where Openbox is

@@ -420,7 +471,7 @@ if (openbox->state() == Openbox::State_Starting)

_client->ignore_unmaps += 2; // select the event mask on the client's parent (to receive config/map req's) - XSelectInput(**otk::display, _plate.window(), SubstructureRedirectMask); + XSelectInput(**otk::display, _plate, SubstructureRedirectMask); // map the client so it maps when the frame does XMapWindow(**otk::display, _client->window());

@@ -444,7 +495,7 @@ } else {

// according to the ICCCM - if the client doesn't reparent itself, then we // will reparent the window to root for them XReparentWindow(**otk::display, _client->window(), - _screen->rootWindow(), + otk::display->screenInfo(_client->screen())->rootWindow(), _client->area().x(), _client->area().y()); } }
M src/frame.hhsrc/frame.hh

@@ -9,28 +9,43 @@ extern "C" {

#include <X11/Xlib.h> } -#include "client.hh" -#include "backgroundwidget.hh" -#include "labelwidget.hh" -#include "buttonwidget.hh" +#include "python.hh" #include "otk/strut.hh" #include "otk/rect.hh" -#include "otk/screeninfo.hh" #include "otk/renderstyle.hh" -#include "otk/widget.hh" #include "otk/ustring.hh" +#include "otk/surface.hh" +#include "otk/eventhandler.hh" #include <string> namespace ob { +class Client; + +//! Varius geometry settings in the frame decorations +struct FrameGeometry { + unsigned int width; // title and handle + unsigned int font_height; + unsigned int title_height() { return font_height + bevel*2; } + unsigned int label_width; + unsigned int label_height() { return font_height; } + unsigned int handle_height; // static, from the style + int handle_y; + unsigned int button_size; // static, from the style + unsigned grip_width() { return button_size * 2; } + unsigned bevel; // static, from the style + unsigned bwidth; // frame elements' border width + unsigned cbwidth; // client border width +}; + //! Holds and decorates a frame around an Client (client window) /*! The frame is responsible for calling XSelectInput on the client window's new parent with the SubstructureRedirectMask so that structure events for the client are sent to the window manager. */ -class Frame : public otk::Widget, public WidgetBase { +class Frame : public otk::StyleNotify, public otk::EventHandler { public: //! The event mask to grab on frame windows

@@ -38,7 +53,6 @@ static const long event_mask = EnterWindowMask | LeaveWindowMask;

private: Client *_client; - const otk::ScreenInfo *_screen; //! The size of the frame on each side of the client window otk::Strut _size;

@@ -46,32 +60,45 @@

//! The size of the frame on each side of the client window inside the border otk::Strut _innersize; + //! The position and size of the entire frame (including borders) + otk::Rect _area; + + bool _visible; + // decoration windows - BackgroundWidget _plate; // sits entirely under the client window - BackgroundWidget _titlebar; - ButtonWidget _button_close; - ButtonWidget _button_iconify; - ButtonWidget _button_max; - ButtonWidget _button_alldesk; - LabelWidget _label; - BackgroundWidget _handle; - ButtonWidget _grip_left; - ButtonWidget _grip_right; + Window _frame; // sits under everything + Window _plate; // sits entirely under the client window + Window _title; // the titlebar + Window _label; // the section of the titlebar which shows the window name + Window _handle; // bottom bar + Window _lgrip; // lefthand resize grab on the handle + Window _rgrip; // righthand resize grab on the handle + Window *_buttons; // all of the titlebar buttons + unsigned int _numbuttons; // number of buttons, size of _buttons array + unsigned int *_titleorder; // order of the buttons and the label (always + // holds '_numbuttons + 1' elements (for the + // label, which is coded as '-1') - //! The decorations to display on the window. - /*! - This is by default the same value as in the Client::decorations, but it - is duplicated here so that it can be overridden per-window by the user. - */ - Client::DecorationFlags _decorations; + // surfaces for each + otk::Surface *_frame_sur; + otk::Surface *_title_sur; + otk::Surface *_label_sur; + otk::Surface *_handle_sur; + otk::Surface *_grip_sur; + otk::Surface **_buttons_sur; + + FrameGeometry geom; + + void applyStyle(const otk::RenderStyle &style); + void layoutTitle(); + void renderLabel(); public: - //! Constructs an Frame object, and reparents the client to itself + //! Constructs an Frame object for a client /*! - @param client The client window which will be decorated by the new Frame - @param style The style to use to decorate the frame + @param client The client which will be decorated by the new Frame */ - Frame(Client *client, otk::RenderStyle *style); + Frame(Client *client); //! Destroys the Frame object virtual ~Frame();

@@ -79,18 +106,8 @@ //! Returns the size of the frame on each side of the client

const otk::Strut& size() const { return _size; } //! Set the style to decorate the frame with - virtual void setStyle(otk::RenderStyle *style); - - //! Empty overridden method to prevent automatic alignment of children - virtual void adjust(); - - //! Displays focused decorations - virtual void focus(); - //! Displays unfocused decorations - virtual void unfocus(); + virtual void styleChanged(const otk::RenderStyle &style); - void setTitle(const otk::ustring &text); - //! Reparents the client window from the root window onto the frame void grabClient(); //! Reparents the client window back to the root window

@@ -103,8 +120,10 @@ void adjustPosition();

//! Shape the frame window to the client window void adjustShape(); //! Update the frame to match the client's new state (for things like toggle - //! buttons) + //! buttons, focus, and the title) XXX break this up void adjustState(); + void adjustFocus(); + void adjustTitle(); //! Applies gravity to the client's position to find where the frame should //! be positioned.

@@ -120,27 +139,32 @@ @return The proper coordinates for the client, based on the frame.

*/ void frameGravity(int &x, int &y); - //! Gets the window id of the frame's "plate" subelement - inline Window plate() const { return _plate.window(); } - //! Gets the window id of the frame's "titlebar" subelement - inline Window titlebar() const { return _titlebar.window(); } - //! Gets the window id of the frame's "label" subelement - inline Window label() const { return _label.window(); } - //! Gets the window id of the frame's "close button" subelement - inline Window button_close() const { return _button_close.window(); } - //! Gets the window id of the frame's "iconify button" subelement - inline Window button_iconify() const { return _button_iconify.window(); } - //! Gets the window id of the frame's "maximize button" subelement - inline Window button_max() const { return _button_max.window(); } - //! Gets the window id of the frame's "all desktops button" subelement - inline Window button_alldesk() const { return _button_alldesk.window(); } - //! Gets the window id of the frame's "handle" subelement - inline Window handle() const { return _handle.window(); } - //! Gets the window id of the frame's "left grip" subelement - inline Window grip_left() const { return _grip_left.window(); } - //! Gets the window id of the frame's "right grip" subelement - inline Window grip_right() const { return _grip_right.window(); } + //! The position and size of the frame window + inline const otk::Rect& area() const { return _area; } + + //! Returns if the frame is visible + inline bool visible() const { return _visible; } + //! Shows the frame + void show(); + //! Hides the frame + void hide(); + + //! Returns the MouseContext for the given window id + /*! + Returns '-1' if no valid mouse context exists in the frame for the given + id. + */ + ob::MouseContext::MC mouseContext(Window win) const; + + //! Gets the window id of the frame's base top-level parent + inline Window window() const { return _frame; } + //! Gets the window id of the client's parent window + inline Window plate() const { return _plate; } + + //! Returns a null terminated array of the window ids that make up the + //! frame's decorations. + Window *allWindows() const; }; }
D src/labelwidget.cc

@@ -1,117 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "otk/screeninfo.hh" -#include "otk/display.hh" -#include "labelwidget.hh" - -namespace ob { - -LabelWidget::LabelWidget(otk::Widget *parent, WidgetBase::WidgetType type) - : otk::Widget(parent), - WidgetBase(type) -{ -} - - -LabelWidget::~LabelWidget() -{ -} - - -void LabelWidget::setText(const otk::ustring &text) -{ - _text = text; - _dirty = true; -} - - -void LabelWidget::setTextures() -{ - if (_focused) { - setTexture(_style->labelFocusBackground()); - _text_color = _style->textFocusColor(); - } else { - setTexture(_style->labelUnfocusBackground()); - _text_color = _style->textUnfocusColor(); - } -} - - -void LabelWidget::setStyle(otk::RenderStyle *style) -{ - otk::Widget::setStyle(style); - setTextures(); - _font = style->labelFont(); - _sidemargin = style->bevelWidth() * 2; - _justify = style->labelTextJustify(); - - assert(_font); -} - - -void LabelWidget::focus() -{ - otk::Widget::focus(); - setTextures(); -} - - -void LabelWidget::unfocus() -{ - otk::Widget::unfocus(); - setTextures(); -} - - -void LabelWidget::renderForeground() -{ - bool draw = _dirty; - - otk::Widget::renderForeground(); - - if (draw) { - otk::ustring 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::RenderStyle::RightJustify: - x += max_length - length; - break; - case otk::RenderStyle::CenterJustify: - x += (max_length - length) / 2; - break; - case otk::RenderStyle::LeftJustify: - break; - } - } - - otk::display->renderControl(_screen)->drawString - (*_surface, *_font, x, 0, *_text_color, t); - } -} - - -void LabelWidget::adjust() -{ - // nothing to adjust. no children. -} - -}
D src/labelwidget.hh

@@ -1,42 +0,0 @@

-// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifndef __oblabelwidget_hh -#define __oblabelwidget_hh - -#include "widgetbase.hh" -#include "otk/widget.hh" -#include "otk/font.hh" -#include "otk/renderstyle.hh" -#include "otk/ustring.hh" - -namespace ob { - -class LabelWidget : public otk::Widget, public WidgetBase -{ -private: - void setTextures(); - const otk::Font *_font; - otk::RenderColor *_text_color; - int _sidemargin; - otk::RenderStyle::TextJustify _justify; - otk::ustring _text; - -public: - LabelWidget(otk::Widget *parent, WidgetBase::WidgetType type); - virtual ~LabelWidget(); - - virtual void setStyle(otk::RenderStyle *style); - - virtual void adjust(); - - virtual void focus(); - virtual void unfocus(); - - virtual void renderForeground(); - - inline const otk::ustring &text() const { return _text; } - void setText(const otk::ustring &text); -}; - -} - -#endif // __oblabelwidget_hh
M src/openbox.ccsrc/openbox.cc

@@ -15,6 +15,7 @@ #include "otk/assassin.hh"

#include "otk/property.hh" #include "otk/util.hh" #include "otk/rendercolor.hh" +#include "otk/renderstyle.hh" extern "C" { #include <X11/cursorfont.h>

@@ -120,6 +121,7 @@ // anything that died while we were restarting won't give us a SIGCHLD

while (waitpid(-1, NULL, WNOHANG) > 0); otk::RenderColor::initialize(); + otk::RenderStyle::initialize(); otk::Timer::initialize(); otk::Property::initialize(); _actions = new Actions();

@@ -180,7 +182,7 @@ ScreenList::iterator it, end = _screens.end();

for (it = _screens.begin(); it != end; ++it) { (*it)->manageExisting(); } - + // grab any keys set up before the screens existed _bindings->grabKeys(true);

@@ -212,6 +214,7 @@ // all im gunna do is the same.

//delete _display; otk::Timer::destroy(); + otk::RenderStyle::destroy(); otk::RenderColor::destroy(); }
M src/screen.ccsrc/screen.cc

@@ -48,8 +48,7 @@

Screen::Screen(int screen) : WidgetBase(WidgetBase::Type_Root), - _number(screen), - _style(screen, "") + _number(screen) { assert(screen >= 0); assert(screen < ScreenCount(**otk::display)); _info = otk::display->screenInfo(screen);

@@ -91,14 +90,15 @@ }

} _style.load(sconfig); */ - otk::display->renderControl(_number)->drawRoot(*_style.rootColor()); + otk::display->renderControl(_number)-> + drawRoot(*otk::RenderStyle::style(_number)->rootColor()); // set up notification of netwm support changeSupportedAtoms(); // Set the netwm properties for geometry - unsigned long geometry[] = { _info->width(), - _info->height() }; + unsigned long geometry[] = { _info->size().width(), + _info->size().height() }; otk::Property::set(_info->rootWindow(), otk::Property::atoms.net_desktop_geometry, otk::Property::atoms.cardinal, geometry, 2);

@@ -237,9 +237,9 @@ xineramaUsableArea = getXineramaAreas();

#endif // XINERAMA */ - _area.setRect(_strut.left, _strut.top, - _info->width() - (_strut.left + _strut.right), - _info->height() - (_strut.top + _strut.bottom)); + _area = otk::Rect(_strut.left, _strut.top, + _info->size().width() - (_strut.left + _strut.right), + _info->size().height() - (_strut.top + _strut.bottom)); /* #ifdef XINERAMA

@@ -494,7 +494,7 @@ // reparented back to root automatically

XChangeSaveSet(**otk::display, window, SetModeInsert); // create the decoration frame for the client window - client->frame = new Frame(client, &_style); + client->frame = new Frame(client); // register the plate for events (map req's) // this involves removing itself from the handler list first, since it is // auto added to the list, being a widget. we won't get any events on the

@@ -503,17 +503,10 @@ openbox->clearHandler(client->frame->plate());

openbox->registerHandler(client->frame->plate(), client); // add to the wm's map - openbox->addClient(client->frame->window(), client); - openbox->addClient(client->frame->plate(), client); - openbox->addClient(client->frame->titlebar(), client); - openbox->addClient(client->frame->label(), client); - openbox->addClient(client->frame->button_max(), client); - openbox->addClient(client->frame->button_iconify(), client); - openbox->addClient(client->frame->button_alldesk(), client); - openbox->addClient(client->frame->button_close(), client); - openbox->addClient(client->frame->handle(), client); - openbox->addClient(client->frame->grip_left(), client); - openbox->addClient(client->frame->grip_right(), client); + Window *w = client->frame->allWindows(); + for (unsigned int i = 0; w[i]; ++i) + openbox->addClient(w[i], client); + delete [] w; // reparent the client to the frame client->frame->grabClient();

@@ -573,17 +566,10 @@ openbox->bindings()->grabButtons(false, client);

// remove from the wm's map openbox->removeClient(client->window()); - openbox->removeClient(frame->window()); - openbox->removeClient(frame->plate()); - openbox->removeClient(frame->titlebar()); - openbox->removeClient(frame->label()); - openbox->removeClient(frame->button_max()); - openbox->removeClient(frame->button_iconify()); - openbox->removeClient(frame->button_alldesk()); - openbox->removeClient(frame->button_close()); - openbox->removeClient(frame->handle()); - openbox->removeClient(frame->grip_left()); - openbox->removeClient(frame->grip_right()); + Window *w = frame->allWindows(); + for (unsigned int i = 0; w[i]; ++i) + openbox->addClient(w[i], client); + delete [] w; // unregister for handling events openbox->clearHandler(client->window());
M src/screen.hhsrc/screen.hh

@@ -11,7 +11,6 @@ #include <X11/Xlib.h>

} #include "widgetbase.hh" -#include "otk/renderstyle.hh" #include "otk/strut.hh" #include "otk/rect.hh" #include "otk/screeninfo.hh"

@@ -58,9 +57,6 @@

//! Information about this screen const otk::ScreenInfo *_info; - //! The style with which to render on the screen - otk::RenderStyle _style; - //! Is the root colormap currently installed? bool _root_cmap_installed;

@@ -146,8 +142,6 @@ */

inline bool managed() const { return _managed; } //! Returns the area of the screen not reserved by applications' Struts inline const otk::Rect &area() const { return _area; } - //! Returns the style in use on the screen - inline const otk::RenderStyle *style() const { return &_style; } //! An offscreen window which gets focus when nothing else has it inline Window focuswindow() const { return _focuswindow; } //! Returns the desktop being displayed