all repos — openbox @ f424471009859c23309428e38002c29f4e4d2bc5

openbox fork - make it a bit more like ryudo

frames' subemelents are created and positioned and everything
Dana Jansens danakj@orodu.net
commit

f424471009859c23309428e38002c29f4e4d2bc5

parent

633df648c9d04c6225fba3004c93e497301293bd

4 files changed, 302 insertions(+), 18 deletions(-)

jump to
M otk/style.hhotk/style.hh

@@ -87,6 +87,8 @@ inline unsigned int getBevelWidth(void) const { return bevel_width; }

inline unsigned int getFrameWidth(void) const { return frame_width; } inline unsigned int getBorderWidth(void) const { return border_width; } + inline const BFont *getFont() const { return font; } + inline void setImageControl(BImageControl *c) { image_control = c; } inline void setScreenNumber(unsigned int scr) { screen_number = scr; }
M src/client.hhsrc/client.hh

@@ -93,7 +93,8 @@ Decor_Handle = 1 << 1, //!< Display a handle (bottom)

Decor_Border = 1 << 2, //!< Display a border Decor_Iconify = 1 << 3, //!< Display an iconify button Decor_Maximize = 1 << 4, //!< Display a maximize button - Decor_Close = 1 << 5 //!< Display a close button + Decor_Sticky = 1 << 5, //!< Display a sticky button + Decor_Close = 1 << 6 //!< Display a close button }; //! Holds a bitmask of OBClient::Decoration values typedef unsigned char DecorationFlags;
M src/frame.ccsrc/frame.cc

@@ -14,6 +14,8 @@ #include "frame.hh"

#include "client.hh" #include "otk/display.hh" +#include <string> + namespace ob { OBFrame::OBFrame(const OBClient *client, const otk::Style *style)

@@ -22,13 +24,39 @@ _screen(otk::OBDisplay::screenInfo(client->screen()))

{ assert(client); assert(style); - + + _decorations = client->decorations(); + _style = 0; loadStyle(style); + // create the base frame parent window _window = createFrame(); assert(_window); + // create all of the style element child windows + _titlebar = createChild(_window, 0); + assert(_titlebar); + _button_iconify = createChild(_titlebar, 0); + assert(_button_iconify); + _button_max = createChild(_titlebar, 0); + assert(_button_max); + _button_stick = createChild(_titlebar, 0); + assert(_button_stick); + _button_close = createChild(_titlebar, 0); + assert(_button_close); + _label = createChild(_titlebar, 0); + assert(_label); + XMapSubwindows(otk::OBDisplay::display, _titlebar); + + _handle = createChild(_window, 0); + assert(_handle); + _grip_left = createChild(_handle, 0); + assert(_grip_left); + _grip_right = createChild(_handle, 0); + assert(_grip_right); + XMapSubwindows(otk::OBDisplay::display, _handle); + grabClient(); }

@@ -36,6 +64,16 @@

OBFrame::~OBFrame() { releaseClient(false); + + XDestroyWindow(otk::OBDisplay::display, _titlebar); + XDestroyWindow(otk::OBDisplay::display, _button_iconify); + XDestroyWindow(otk::OBDisplay::display, _button_max); + XDestroyWindow(otk::OBDisplay::display, _button_stick); + XDestroyWindow(otk::OBDisplay::display, _button_close); + XDestroyWindow(otk::OBDisplay::display, _label); + XDestroyWindow(otk::OBDisplay::display, _handle); + XDestroyWindow(otk::OBDisplay::display, _grip_left); + XDestroyWindow(otk::OBDisplay::display, _grip_right); }

@@ -53,34 +91,222 @@ // XXX: do shit here whatever

} _style = style; - - // XXX: load shit like this from the style! - _size.left = _size.top = _size.bottom = _size.right = 2; if (replace) { - resize(); + update(); XSetWindowBorderWidth(otk::OBDisplay::display, _window, _style->getBorderWidth()); - XMoveWindow(otk::OBDisplay::display, _client->window(), - _size.left, _size.top); - // XXX: make everything redraw } } -void OBFrame::resize() +void OBFrame::update() { + // XXX: only if not overridden or something!!! MORE LOGIC HERE!! + _decorations = _client->decorations(); + + int width; // the width of the client window and the border around it + + if (_decorations & OBClient::Decor_Border) { + _size.left = _size.top = _size.bottom = _size.right = + _style->getBorderWidth() + _style->getFrameWidth(); + width = _client->area().width() + _style->getFrameWidth() * 2; + } else { + _size.left = _size.top = _size.bottom = _size.right = 0; + width = _client->area().width(); + } + + if (_decorations & OBClient::Decor_Titlebar) { + _titlebar_area.setRect(0, 0, width, + (_style->getFont()->height() + + _style->getFrameWidth() * 2)); + _size.top += _titlebar_area.height(); + + // set the label size + _label_area.setRect(0, _style->getBevelWidth(), + width, (_titlebar_area.height() - + _style->getBevelWidth() * 2)); + // set the buttons sizes + if (_decorations & OBClient::Decor_Iconify) + _button_iconify_area.setRect(0, _style->getBevelWidth() + 1, + _label_area.height() - 2, + _label_area.height() - 2); + if (_decorations & OBClient::Decor_Maximize) + _button_max_area.setRect(0, _style->getBevelWidth() + 1, + _label_area.height() - 2, + _label_area.height() - 2); + if (_decorations & OBClient::Decor_Sticky) + _button_stick_area.setRect(0, _style->getBevelWidth() + 1, + _label_area.height() - 2, + _label_area.height() - 2); + if (_decorations & OBClient::Decor_Close) + _button_close_area.setRect(0, _style->getBevelWidth() + 1, + _label_area.height() - 2, + _label_area.height() - 2); + + // separation between titlebar elements + const int sep = _style->getBevelWidth() + 1; + + std::string layout = "ILMC"; // XXX: get this from somewhere + // XXX: it is REQUIRED that by this point, the string only has one of each + // possible letter, all of the letters are valid, and L exists somewhere in + // the string! + + int x = sep; + for (int i = 0, len = layout.size(); i < len; ++i) { + otk::Rect *area; + switch (layout[i]) { + case 'I': + if (!(_decorations & OBClient::Decor_Iconify)) + continue; // skip it + area = &_button_iconify_area; + break; + case 'L': + area = &_label_area; + break; + case 'M': + if (!(_decorations & OBClient::Decor_Maximize)) + continue; // skip it + area = &_button_max_area; + break; + case 'S': + if (!(_decorations & OBClient::Decor_Sticky)) + continue; // skip it + area = &_button_stick_area; + break; + case 'C': + if (!(_decorations & OBClient::Decor_Close)) + continue; // skip it + area = &_button_close_area; + break; + default: + assert(false); // the layout string is invalid! + continue; // just to fuck with g++ + } + area->setX(x); + x += sep + area->width(); + } + } + + if (_decorations & OBClient::Decor_Handle) { + _handle_area.setRect(0, _size.top + _client->area().height(), + width, _style->getHandleWidth()); + _grip_left_area.setRect(0, + _handle_area.y() + _handle_area.height(), + // XXX: get a Point class in otk and use that for + // the 'buttons size' since theyre all the same + _button_iconify_area.width() * 2, + _handle_area.height()); + _grip_right_area.setRect(((_handle_area.right() + 1) - + _button_iconify_area.width() * 2), + _handle_area.y() + _handle_area.height(), + // XXX: get a Point class in otk and use that for + // the 'buttons size' since theyre all the same + _button_iconify_area.width() * 2, + _handle_area.height()); + _size.bottom += _handle_area.height(); + } + + + // position/size all the windows + XResizeWindow(otk::OBDisplay::display, _window, _size.left + _size.right + _client->area().width(), _size.top + _size.bottom + _client->area().height()); + + XMoveWindow(otk::OBDisplay::display, _client->window(), + _size.left, _size.top); + + if (_decorations & OBClient::Decor_Titlebar) { + XMoveResizeWindow(otk::OBDisplay::display, _titlebar, + _titlebar_area.x(), _titlebar_area.y(), + _titlebar_area.width(), _titlebar_area.height()); + XMoveResizeWindow(otk::OBDisplay::display, _label, + _label_area.x(), _label_area.y(), + _label_area.width(), _label_area.height()); + if (_decorations & OBClient::Decor_Iconify) + XMoveResizeWindow(otk::OBDisplay::display, _button_iconify, + _button_iconify_area.x(), _button_iconify_area.y(), + _button_iconify_area.width(), + _button_iconify_area.height()); + if (_decorations & OBClient::Decor_Maximize) + XMoveResizeWindow(otk::OBDisplay::display, _button_max, + _button_max_area.x(), _button_max_area.y(), + _button_max_area.width(), + _button_max_area.height()); + if (_decorations & OBClient::Decor_Sticky) + XMoveResizeWindow(otk::OBDisplay::display, _button_stick, + _button_stick_area.x(), _button_stick_area.y(), + _button_stick_area.width(), + _button_stick_area.height()); + if (_decorations & OBClient::Decor_Close) + XMoveResizeWindow(otk::OBDisplay::display, _button_close, + _button_close_area.x(), _button_close_area.y(), + _button_close_area.width(), + _button_close_area.height()); + } + + if (_decorations & OBClient::Decor_Handle) { + XMoveResizeWindow(otk::OBDisplay::display, _handle, + _handle_area.x(), _handle_area.y(), + _handle_area.width(), _handle_area.height()); + XMoveResizeWindow(otk::OBDisplay::display, _grip_left, + _grip_left_area.x(), _grip_left_area.y(), + _grip_left_area.width(), _grip_left_area.height()); + XMoveResizeWindow(otk::OBDisplay::display, _grip_right, + _grip_right_area.x(), _grip_right_area.y(), + _grip_right_area.width(), _grip_right_area.height()); + } + + // map/unmap all the windows + if (_decorations & OBClient::Decor_Titlebar) { + XMapWindow(otk::OBDisplay::display, _titlebar); + XMapWindow(otk::OBDisplay::display, _label); + if (_decorations & OBClient::Decor_Iconify) + XMapWindow(otk::OBDisplay::display, _button_iconify); + else + XUnmapWindow(otk::OBDisplay::display, _button_iconify); + if (_decorations & OBClient::Decor_Maximize) + XMapWindow(otk::OBDisplay::display, _button_max); + else + XUnmapWindow(otk::OBDisplay::display, _button_max); + if (_decorations & OBClient::Decor_Sticky) + XMapWindow(otk::OBDisplay::display, _button_stick); + else + XUnmapWindow(otk::OBDisplay::display, _button_stick); + if (_decorations & OBClient::Decor_Close) + XMapWindow(otk::OBDisplay::display, _button_close); + else + XUnmapWindow(otk::OBDisplay::display, _button_close); + } else { + XUnmapWindow(otk::OBDisplay::display, _titlebar); + XUnmapWindow(otk::OBDisplay::display, _label); + XUnmapWindow(otk::OBDisplay::display, _button_iconify); + XUnmapWindow(otk::OBDisplay::display, _button_max); + XUnmapWindow(otk::OBDisplay::display, _button_stick); + XUnmapWindow(otk::OBDisplay::display, _button_close); + } + + if (_decorations & OBClient::Decor_Handle) { + XMapWindow(otk::OBDisplay::display, _handle); + XMapWindow(otk::OBDisplay::display, _grip_left); + XMapWindow(otk::OBDisplay::display, _grip_right); + } else { + XUnmapWindow(otk::OBDisplay::display, _handle); + XUnmapWindow(otk::OBDisplay::display, _grip_left); + XUnmapWindow(otk::OBDisplay::display, _grip_right); + } + // XXX: more is gunna have to happen here + + updateShape(); } -void OBFrame::shape() +void OBFrame::updateShape() { #ifdef SHAPE if (!_client->shaped()) {

@@ -147,8 +373,7 @@ XMapWindow(otk::OBDisplay::display, _client->window());

XUngrabServer(otk::OBDisplay::display); - resize(); - shape(); + update(); }

@@ -171,6 +396,26 @@

// if we want to remap the window, do so now if (remap) XMapWindow(otk::OBDisplay::display, _client->window()); +} + + +Window OBFrame::createChild(Window parent, Cursor cursor) +{ + XSetWindowAttributes attrib_create; + unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask; + + attrib_create.background_pixmap = None; + attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | ExposureMask; + + if (cursor) { + create_mask |= CWCursor; + attrib_create.cursor = cursor; + } + + return XCreateWindow(otk::OBDisplay::display, parent, 0, 0, 1, 1, 0, + _screen->getDepth(), InputOutput, _screen->getVisual(), + create_mask, &attrib_create); }
M src/frame.hhsrc/frame.hh

@@ -11,14 +11,13 @@ }

#include <string> +#include "client.hh" #include "otk/strut.hh" #include "otk/rect.hh" #include "otk/screeninfo.hh" #include "otk/style.hh" namespace ob { - -class OBClient; //! Holds and decorates a frame around an OBClient (client window) /*!

@@ -36,8 +35,45 @@ Window _window;

//! The size of the frame on each side of the client window otk::Strut _size; + // decoration windows + Window _titlebar; + otk::Rect _titlebar_area; + + Window _button_close; + otk::Rect _button_close_area; + + Window _button_iconify; + otk::Rect _button_iconify_area; + + Window _button_max; + otk::Rect _button_max_area; + + Window _button_stick; + otk::Rect _button_stick_area; + + Window _label; + otk::Rect _label_area; + + Window _handle; + otk::Rect _handle_area; + + Window _grip_left; + otk::Rect _grip_left_area; + + Window _grip_right; + otk::Rect _grip_right_area; + + //! The decorations to display on the window. + /*! + This is by default the same value as in the OBClient::decorations, but it + is duplicated here so that it can be overridden per-window by the user. + */ + OBClient::DecorationFlags _decorations; + //! Creates the base frame window Window createFrame(); + //! Creates a child frame decoration element window + Window createChild(Window parent, Cursor cursor); //! Reparents the client window from the root window onto the frame void grabClient();

@@ -60,10 +96,10 @@

//! Load a style to decorate the frame with void loadStyle(const otk::Style *style); - //! Size the frame to the client - void resize(); + //! Update the frame to match the client + void update(); //! Shape the frame window to the client window - void shape(); + void updateShape(); //! Returns the frame's most-parent window, which is a child of the root //! window