#include <X11/Xlib.h>
}
-#include "client.hh"
+#include "python.hh"
#include "otk/strut.hh"
#include "otk/rect.hh"
-#include "otk/screeninfo.hh"
-#include "otk/style.hh"
+#include "otk/renderstyle.hh"
+#include "otk/ustring.hh"
+#include "otk/surface.hh"
+#include "otk/eventhandler.hh"
#include <string>
namespace ob {
-//! Holds and decorates a frame around an OBClient (client window)
+class Client;
+
+//! Varius geometry settings in the frame decorations
+struct FrameGeometry {
+ int width; // title and handle
+ int font_height;
+ int title_height() { return font_height + bevel*2; }
+ int label_width;
+ int label_height() { return font_height; }
+ int handle_height; // static, from the style
+ int handle_y;
+ int button_size; // static, from the style
+ int grip_width() { return button_size * 2; }
+ int bevel; // static, from the style
+ int bwidth; // frame elements' border width
+ int 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 OBFrame {
-private:
- OBClient *_client;
- const otk::ScreenInfo *_screen;
+class Frame : public otk::StyleNotify, public otk::EventHandler {
+public:
- //! The style to use for size and display the decorations
- const otk::Style *_style;
+ //! The event mask to grab on frame windows
+ static const long event_mask = EnterWindowMask | LeaveWindowMask;
+
+private:
+ Client *_client;
- //! The window id of the base frame window
- 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;
+ //! The size of the frame on each side of the client window inside the border
+ otk::Strut _innersize;
- Window _handle;
- otk::Rect _handle_area;
+ //! The position and size of the entire frame (including borders)
+ otk::Rect _area;
- Window _grip_left;
- otk::Rect _grip_left_area;
-
- Window _grip_right;
- otk::Rect _grip_right_area;
+ bool _visible;
+
+ // decoration windows
+ 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
+ int _numbuttons; // number of buttons, size of _buttons array
+ int *_titleorder; // order of the buttons and the label (always
+ // holds '_numbuttons + 1' elements (for the
+ // label, which is coded as '-1')
+
+ // 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();
- //! The decorations to display on the window.
+public:
+ //! Constructs an Frame object for a client
/*!
- 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.
+ @param client The client which will be decorated by the new Frame
*/
- OBClient::DecorationFlags _decorations;
+ Frame(Client *client);
+ //! Destroys the Frame object
+ virtual ~Frame();
- //! Creates the base frame window
- Window createFrame();
- //! Creates a child frame decoration element window
- Window createChild(Window parent, Cursor cursor);
+ //! 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 styleChanged(const otk::RenderStyle &style);
//! Reparents the client window from the root window onto the frame
void grabClient();
//! Reparents the client window back to the root window
+ void releaseClient();
+
+ //! Update the frame's size to match the client
+ void adjustSize();
+ //! Update the frame's position to match the client
+ 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, 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.
/*!
- @param remap Re-map the client window when we're done reparenting?
+ @return The proper coordinates for the frame, based on the client.
*/
- void releaseClient(bool remap);
+ void clientGravity(int &x, int &y);
-public:
- //! Constructs an OBFrame object, and reparents the client to itself
+ //! Reversly applies gravity to the frame's position to find where the client
+ //! should be positioned.
/*!
- @param client The client window which will be decorated by the new OBFrame
- @param style The style to use to decorate the frame
+ @return The proper coordinates for the client, based on the frame.
*/
- OBFrame(OBClient *client, const otk::Style *style);
- //! Destroys the OBFrame object
- virtual ~OBFrame();
+ void frameGravity(int &x, int &y);
- //! Load a style to decorate the frame with
- void loadStyle(const otk::Style *style);
+ //! The position and size of the frame window
+ inline const otk::Rect& area() const { return _area; }
- //! Update the frame to match the client
- void update();
- //! Shape the frame window to the client window
- void updateShape();
-
- //! Returns the frame's most-parent window, which is a child of the root
- //! window
- inline Window window() const { return _window; }
-
- inline Window titlebar() const { return _titlebar; }
- inline Window label() const { return _label; }
- inline Window buttonIconify() const { return _button_iconify; }
- inline Window buttonMax() const { return _button_max; }
- inline Window buttonStick() const { return _button_stick; }
- inline Window buttonClose() const { return _button_close; }
- inline Window handle() const { return _handle; }
- inline Window gripLeft() const { return _grip_left; }
- inline Window gripRight() const { return _grip_right; }
+ //! 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;
};
}