summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-04-13 07:18:28 +0000
committerDana Jansens <danakj@orodu.net>2003-04-13 07:18:28 +0000
commit5cf61ee02354c1c9f80c11f3796afc4b948055d6 (patch)
tree5530ecca55e11cc74e57db07d750447c7107f8ed /openbox
parentfb1696659672386bcfc0f753b67f9eeda74e93b9 (diff)
move the openbox engine into librender and the kernel. the theme is loaded and stored inside librender. the frame is decorated and managed inside the kernel.
Diffstat (limited to 'openbox')
-rw-r--r--openbox/.cvsignore22
-rw-r--r--openbox/action.c11
-rw-r--r--openbox/client.c31
-rw-r--r--openbox/config.h15
-rw-r--r--openbox/engine.c108
-rw-r--r--openbox/engine.h30
-rw-r--r--openbox/event.c35
-rw-r--r--openbox/focus.c1
-rw-r--r--openbox/frame.c634
-rw-r--r--openbox/frame.h65
-rw-r--r--openbox/framerender.c248
-rw-r--r--openbox/framerender.h11
-rw-r--r--openbox/openbox.c20
-rw-r--r--openbox/parse.l6
-rw-r--r--openbox/parse.y14
-rw-r--r--openbox/screen.c9
16 files changed, 1058 insertions, 202 deletions
diff --git a/openbox/.cvsignore b/openbox/.cvsignore
index 5060e191..b4b3cfc3 100644
--- a/openbox/.cvsignore
+++ b/openbox/.cvsignore
@@ -4,3 +4,25 @@ parse.tab.c
parse.tab.h
.libs
parse.lex.c
+action.lo
+client.lo
+config.lo
+dispatch.lo
+event.lo
+extensions.lo
+focus.lo
+frame.lo
+framerender.lo
+grab.lo
+group.lo
+menu.lo
+openbox.lo
+parse.lex.lo
+parse.lo
+parse.tab.lo
+plugin.lo
+prop.lo
+screen.lo
+stacking.lo
+timer.lo
+xerror.lo
diff --git a/openbox/action.c b/openbox/action.c
index a9c7737a..683e205f 100644
--- a/openbox/action.c
+++ b/openbox/action.c
@@ -2,12 +2,11 @@
#include "focus.h"
#include "stacking.h"
#include "frame.h"
+#include "framerender.h"
#include "screen.h"
#include "action.h"
#include "dispatch.h"
#include "openbox.h"
-#include "engine.h"
-#include "render/render.h"
#include <glib.h>
@@ -649,10 +648,10 @@ static void popup_coords(char *format, int a, int b, gboolean hide)
char *text;
text = g_strdup_printf(format, a, b);
- engine_size_label(text, TRUE, TRUE, &s);
+ framerender_size_popup_label(text, &s);
XMoveResizeWindow(ob_display, coords,
10, 10, s.width, s.height);
- engine_render_label(coords, &s, text, TRUE, TRUE);
+ framerender_popup_label(coords, &s, text);
g_free(text);
XMapWindow(ob_display, coords);
@@ -733,12 +732,12 @@ static void popup_cycle(Client *c, gboolean hide)
a = screen_area(c->desktop);
- engine_size_label(c->title, TRUE, TRUE, &s);
+ framerender_size_popup_label(c->title, &s);
XMoveResizeWindow(ob_display, coords,
a->x + (a->width - s.width) / 2,
a->y + (a->height - s.height) / 2,
s.width, s.height);
- engine_render_label(coords, &s, c->title, TRUE, TRUE);
+ framerender_popup_label(coords, &s, c->title);
XMapWindow(ob_display, coords);
}
diff --git a/openbox/client.c b/openbox/client.c
index e1c391ea..f4dd727b 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -3,7 +3,6 @@
#include "prop.h"
#include "extensions.h"
#include "frame.h"
-#include "engine.h"
#include "event.h"
#include "grab.h"
#include "focus.h"
@@ -206,9 +205,9 @@ void client_manage(Window window)
XChangeSaveSet(ob_display, window, SetModeInsert);
/* create the decoration frame for the client window */
- self->frame = engine_frame_new();
+ self->frame = frame_new();
- engine_frame_grab_client(self->frame, self);
+ frame_grab_client(self->frame, self);
client_apply_startup_state(self);
@@ -290,7 +289,7 @@ void client_unmanage(Client *self)
/* we dont want events no more */
XSelectInput(ob_display, self->window, NoEventMask);
- engine_frame_hide(self->frame);
+ frame_hide(self->frame);
client_list = g_list_remove(client_list, self);
stacking_list = g_list_remove(stacking_list, self);
@@ -347,7 +346,7 @@ void client_unmanage(Client *self)
client_toggle_border(self, TRUE);
/* reparent the window out of the frame, and free the frame */
- engine_frame_release_client(self->frame, self);
+ frame_release_client(self->frame, self);
self->frame = NULL;
if (ob_state != State_Exiting) {
@@ -933,7 +932,7 @@ void client_setup_decor_and_functions(Client *self)
if (self->frame) {
/* change the decors on the frame, and with more/less decorations,
we may also need to be repositioned */
- engine_frame_adjust_area(self->frame, TRUE, TRUE);
+ frame_adjust_area(self->frame, TRUE, TRUE);
/* with new decor, the window's maximized size may change */
client_remaximize(self);
}
@@ -1051,7 +1050,7 @@ void client_update_wmhints(Client *self)
self->pixmap_icon_mask = None;
if (self->frame)
- engine_frame_adjust_icon(self->frame);
+ frame_adjust_icon(self->frame);
}
}
@@ -1100,7 +1099,7 @@ void client_update_title(Client *self)
self->title = data;
if (self->frame)
- engine_frame_adjust_title(self->frame);
+ frame_adjust_title(self->frame);
}
void client_update_icon_title(Client *self)
@@ -1224,7 +1223,7 @@ void client_update_icons(Client *self)
}
if (self->frame)
- engine_frame_adjust_icon(self->frame);
+ frame_adjust_icon(self->frame);
}
void client_update_kwm_icon(Client *self)
@@ -1239,7 +1238,7 @@ void client_update_kwm_icon(Client *self)
self->pixmap_icon = self->pixmap_icon_mask = None;
}
if (self->frame)
- engine_frame_adjust_icon(self->frame);
+ frame_adjust_icon(self->frame);
}
static void client_change_state(Client *self)
@@ -1278,7 +1277,7 @@ static void client_change_state(Client *self)
client_calc_layer(self);
if (self->frame)
- engine_frame_adjust_state(self->frame);
+ frame_adjust_state(self->frame);
}
static Client *search_focus_tree(Client *node, Client *skip)
@@ -1349,9 +1348,9 @@ static void client_showhide(Client *self)
{
if (client_should_show(self))
- engine_frame_show(self->frame);
+ frame_show(self->frame);
else
- engine_frame_hide(self->frame);
+ frame_hide(self->frame);
}
gboolean client_normal(Client *self) {
@@ -1524,7 +1523,7 @@ void client_configure(Client *self, Corner anchor, int x, int y, int w, int h,
/* move/resize the frame to match the request */
if (self->frame) {
if (moved || resized)
- engine_frame_adjust_area(self->frame, moved, resized);
+ frame_adjust_area(self->frame, moved, resized);
if (!user || final) {
XEvent event;
@@ -1790,7 +1789,7 @@ void client_shade(Client *self, gboolean shade)
self->shaded = shade;
client_change_state(self);
/* resize the frame to just the titlebar */
- engine_frame_adjust_area(self->frame, FALSE, FALSE);
+ frame_adjust_area(self->frame, FALSE, FALSE);
}
void client_close(Client *self)
@@ -1839,7 +1838,7 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
self->desktop = target;
PROP_SET32(self->window, net_wm_desktop, cardinal, target);
/* the frame can display the current desktop state */
- engine_frame_adjust_state(self->frame);
+ frame_adjust_state(self->frame);
/* 'move' the window to the new desktop */
if (!donthide)
client_showhide(self);
diff --git a/openbox/config.h b/openbox/config.h
index 0dceb920..b69f74a1 100644
--- a/openbox/config.h
+++ b/openbox/config.h
@@ -12,21 +12,6 @@ extern gboolean config_focus_last;
/*! Focus the last focused window as a fallback when switching desktops */
extern gboolean config_focus_last_on_desktop;
-/*! The engine to load */
-extern char *config_engine_name;
-/*! The theme to load */
-extern char *config_engine_theme;
-/*! The titlebar layout */
-extern char *config_engine_layout;
-/*! The titlebar font */
-extern char *config_engine_font;
-/*! The titlebar font's shadow */
-extern gboolean config_engine_shadow;
-/*! The titlebar font's shadow offset */
-extern int config_engine_shadow_offset;
-/*! The titlebar font's shadow transparency */
-extern int config_engine_shadow_tint;
-
/*! The number of desktops */
extern int config_desktops_num;
/*! Names for the desktops */
diff --git a/openbox/engine.c b/openbox/engine.c
deleted file mode 100644
index 53e10deb..00000000
--- a/openbox/engine.c
+++ /dev/null
@@ -1,108 +0,0 @@
-#include "engine.h"
-#include "config.h"
-
-#include <glib.h>
-#include <gmodule.h>
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-EngineFrameNew *engine_frame_new;
-EngineFrameGrabClient *engine_frame_grab_client;
-EngineFrameReleaseClient *engine_frame_release_client;
-EngineFrameAdjustArea *engine_frame_adjust_area;
-EngineFrameAdjustShape *engine_frame_adjust_shape;
-EngineFrameAdjustState *engine_frame_adjust_state;
-EngineFrameAdjustFocus *engine_frame_adjust_focus;
-EngineFrameAdjustTitle *engine_frame_adjust_title;
-EngineFrameAdjustIcon *engine_frame_adjust_icon;
-EngineFrameShow *engine_frame_show;
-EngineFrameHide *engine_frame_hide;
-EngineGetContext *engine_get_context;
-EngineRenderLabel *engine_render_label;
-EngineSizeLabel *engine_size_label;
-
-static GModule *module = NULL;
-static EngineStartup *estartup = NULL;
-static EngineShutdown *eshutdown = NULL;
-
-#define LOADSYM(name, var) \
- if (!g_module_symbol(module, #name, (gpointer*)&var)) { \
- g_warning("Failed to load symbol %s from engine", #name); \
- return FALSE; \
- }
-
-static gboolean load(char *name)
-{
- char *path;
-
- g_assert(module == NULL);
-
- path = g_build_filename(g_get_home_dir(), ".openbox", "engines", name,
- NULL);
- module = g_module_open(path, 0);
- g_free(path);
-
- if (module == NULL) {
- path = g_build_filename(ENGINEDIR, name, NULL);
- module = g_module_open(path, 0);
- g_free(path);
- }
-
- if (module == NULL) {
- g_warning(g_module_error());
- return FALSE;
- }
-
- /* load the engine's symbols */
- LOADSYM(startup, estartup);
- LOADSYM(shutdown, eshutdown);
- LOADSYM(frame_new, engine_frame_new);
- LOADSYM(frame_grab_client, engine_frame_grab_client);
- LOADSYM(frame_release_client, engine_frame_release_client);
- LOADSYM(frame_adjust_area, engine_frame_adjust_area);
- LOADSYM(frame_adjust_shape, engine_frame_adjust_shape);
- LOADSYM(frame_adjust_state, engine_frame_adjust_state);
- LOADSYM(frame_adjust_focus, engine_frame_adjust_focus);
- LOADSYM(frame_adjust_title, engine_frame_adjust_title);
- LOADSYM(frame_adjust_icon, engine_frame_adjust_icon);
- LOADSYM(frame_show, engine_frame_show);
- LOADSYM(frame_hide, engine_frame_hide);
- LOADSYM(get_context, engine_get_context);
- LOADSYM(render_label, engine_render_label);
- LOADSYM(size_label, engine_size_label);
-
- if (!estartup())
- return FALSE;
-
- return TRUE;
-}
-
-void engine_startup()
-{
- module = NULL;
-}
-
-void engine_load()
-{
- if (load(config_engine_name))
- return;
- g_warning("Failed to load the engine '%s'", config_engine_name);
- g_message("Falling back to the default: '%s'", DEFAULT_ENGINE);
- if (module != NULL) {
- g_module_close(module);
- module = NULL;
- }
- if (!load(DEFAULT_ENGINE)) {
- g_critical("Failed to load the engine '%s'. Aborting", DEFAULT_ENGINE);
- exit(1);
- }
-}
-
-void engine_shutdown()
-{
- if (module != NULL) {
- eshutdown();
- g_module_close(module);
- }
-}
diff --git a/openbox/engine.h b/openbox/engine.h
deleted file mode 100644
index e2c314a6..00000000
--- a/openbox/engine.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __engine_h
-#define __engine_h
-
-#include "../engines/engineinterface.h"
-
-void engine_startup();
-void engine_load();
-void engine_shutdown();
-
-extern EngineFrameNew *engine_frame_new;
-
-extern EngineFrameGrabClient *engine_frame_grab_client;
-extern EngineFrameReleaseClient *engine_frame_release_client;
-
-extern EngineFrameAdjustArea *engine_frame_adjust_area;
-extern EngineFrameAdjustShape *engine_frame_adjust_shape;
-extern EngineFrameAdjustState *engine_frame_adjust_state;
-extern EngineFrameAdjustFocus *engine_frame_adjust_focus;
-extern EngineFrameAdjustTitle *engine_frame_adjust_title;
-extern EngineFrameAdjustIcon *engine_frame_adjust_icon;
-
-extern EngineFrameShow *engine_frame_show;
-extern EngineFrameHide *engine_frame_hide;
-
-extern EngineGetContext *engine_get_context;
-
-extern EngineRenderLabel *engine_render_label;
-extern EngineSizeLabel *engine_size_label;
-
-#endif
diff --git a/openbox/event.c b/openbox/event.c
index 9d31e6bc..4d449f78 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -5,12 +5,11 @@
#include "config.h"
#include "screen.h"
#include "frame.h"
-#include "engine.h"
+#include "framerender.h"
#include "focus.h"
#include "stacking.h"
#include "extensions.h"
#include "timer.h"
-#include "engine.h"
#include "dispatch.h"
#include <X11/Xlib.h>
@@ -368,6 +367,34 @@ static void event_handle_client(Client *client, XEvent *e)
int i=0;
switch (e->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ switch (frame_context(client->frame, e->xbutton.window)) {
+ case Context_Maximize:
+ client->frame->max_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_Close:
+ client->frame->close_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_Iconify:
+ client->frame->iconify_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_AllDesktops:
+ client->frame->desk_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ case Context_Shade:
+ client->frame->shade_press = (e->type == ButtonPress);
+ framerender_frame(client->frame);
+ break;
+ default:
+ /* nothing changes with clicks for any other contexts */
+ break;
+ }
+ break;
case FocusIn:
focus_set_client(client);
case FocusOut:
@@ -377,7 +404,7 @@ static void event_handle_client(Client *client, XEvent *e)
#endif
/* focus state can affect the stacking layer */
client_calc_layer(client);
- engine_frame_adjust_focus(client->frame);
+ frame_adjust_focus(client->frame);
break;
case EnterNotify:
if (client_normal(client)) {
@@ -639,7 +666,7 @@ static void event_handle_client(Client *client, XEvent *e)
#ifdef SHAPE
if (extensions_shape && e->type == extensions_shape_event_basep) {
client->shaped = ((XShapeEvent*)e)->shaped;
- engine_frame_adjust_shape(client->frame);
+ frame_adjust_shape(client->frame);
}
#endif
}
diff --git a/openbox/focus.c b/openbox/focus.c
index 7542fae6..c189bc9e 100644
--- a/openbox/focus.c
+++ b/openbox/focus.c
@@ -9,7 +9,6 @@
#include "dispatch.h"
#include "focus.h"
#include "parse.h"
-#include "engine.h"
#include <X11/Xlib.h>
#include <glib.h>
diff --git a/openbox/frame.c b/openbox/frame.c
index 2064f304..765c4b59 100644
--- a/openbox/frame.c
+++ b/openbox/frame.c
@@ -1,4 +1,615 @@
#include "frame.h"
+#include "openbox.h"
+#include "extensions.h"
+#include "framerender.h"
+#include "render/theme.h"
+
+#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
+#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
+ ButtonPressMask | ButtonReleaseMask)
+#define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
+ ButtonMotionMask | ExposureMask)
+
+static void layout_title(Frame *self);
+
+void frame_startup()
+{
+ RECT_SET(theme_a_focused_pressed_desk->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_pressed_set_desk->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_unpressed_desk->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_desk->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_set_desk->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_unpressed_desk->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_pressed_shade->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_pressed_set_shade->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_unpressed_shade->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_shade->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_set_shade->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_unpressed_shade->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_pressed_iconify->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_unpressed_iconify->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_iconify->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_unpressed_iconify->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_unpressed_iconify->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_pressed_max->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_pressed_set_max->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_unpressed_max->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_max->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_set_max->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_unpressed_max->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_pressed_close->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_focused_unpressed_close->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_pressed_close->area, 0, 0,
+ theme_button_size, theme_button_size);
+ RECT_SET(theme_a_unfocused_unpressed_close->area, 0, 0,
+ theme_button_size, theme_button_size);
+
+ RECT_SET(theme_a_focused_grip->area, 0, 0,
+ theme_grip_width, theme_handle_height);
+ RECT_SET(theme_a_unfocused_grip->area, 0, 0,
+ theme_grip_width, theme_handle_height);
+}
+
+void frame_shutdown()
+{
+}
+
+static Window createWindow(Window parent, unsigned long mask,
+ XSetWindowAttributes *attrib)
+{
+ return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
+ render_depth, InputOutput, render_visual,
+ mask, attrib);
+
+}
+
+Frame *frame_new()
+{
+ XSetWindowAttributes attrib;
+ unsigned long mask;
+ Frame *self;
+
+ self = g_new(Frame, 1);
+
+ self->visible = FALSE;
+
+ /* create all of the decor windows */
+ mask = CWOverrideRedirect | CWEventMask;
+ attrib.event_mask = FRAME_EVENTMASK;
+ attrib.override_redirect = TRUE;
+ self->window = createWindow(ob_root, mask, &attrib);
+
+ mask = 0;
+ self->plate = createWindow(self->window, mask, &attrib);
+
+ mask = CWEventMask;
+ attrib.event_mask = ELEMENT_EVENTMASK;
+ self->title = createWindow(self->window, mask, &attrib);
+ self->label = createWindow(self->title, mask, &attrib);
+ self->max = createWindow(self->title, mask, &attrib);
+ self->close = createWindow(self->title, mask, &attrib);
+ self->desk = createWindow(self->title, mask, &attrib);
+ self->shade = createWindow(self->title, mask, &attrib);
+ self->icon = createWindow(self->title, mask, &attrib);
+ self->iconify = createWindow(self->title, mask, &attrib);
+ self->handle = createWindow(self->window, mask, &attrib);
+ mask |= CWCursor;
+ attrib.cursor = ob_cursors.ll_angle;
+ self->lgrip = createWindow(self->handle, mask, &attrib);
+ attrib.cursor = ob_cursors.lr_angle;
+ self->rgrip = createWindow(self->handle, mask, &attrib);
+
+ /* the other stuff is shown based on decor settings */
+ XMapWindow(ob_display, self->plate);
+ XMapWindow(ob_display, self->lgrip);
+ XMapWindow(ob_display, self->rgrip);
+ XMapWindow(ob_display, self->label);
+
+ /* set colors/appearance/sizes for stuff that doesn't change */
+ XSetWindowBorder(ob_display, self->window, theme_b_color->pixel);
+ XSetWindowBorder(ob_display, self->label, theme_b_color->pixel);
+ XSetWindowBorder(ob_display, self->rgrip, theme_b_color->pixel);
+ XSetWindowBorder(ob_display, self->lgrip, theme_b_color->pixel);
+
+ XResizeWindow(ob_display, self->max, theme_button_size, theme_button_size);
+ XResizeWindow(ob_display, self->iconify,
+ theme_button_size, theme_button_size);
+ XResizeWindow(ob_display, self->icon,
+ theme_button_size, theme_button_size);
+ XResizeWindow(ob_display, self->close,
+ theme_button_size, theme_button_size);
+ XResizeWindow(ob_display, self->desk,
+ theme_button_size, theme_button_size);
+ XResizeWindow(ob_display, self->shade,
+ theme_button_size, theme_button_size);
+ XResizeWindow(ob_display, self->lgrip,
+ theme_grip_width, theme_handle_height);
+ XResizeWindow(ob_display, self->rgrip,
+ theme_grip_width, theme_handle_height);
+
+ /* set up the dynamic appearances */
+ self->a_unfocused_title = appearance_copy(theme_a_unfocused_title);
+ self->a_focused_title = appearance_copy(theme_a_focused_title);
+ self->a_unfocused_label = appearance_copy(theme_a_unfocused_label);
+ self->a_focused_label = appearance_copy(theme_a_focused_label);
+ self->a_unfocused_handle = appearance_copy(theme_a_unfocused_handle);
+ self->a_focused_handle = appearance_copy(theme_a_focused_handle);
+ self->a_icon = appearance_copy(theme_a_icon);
+
+ self->max_press = self->close_press = self->desk_press =
+ self->iconify_press = self->shade_press = FALSE;
+
+ return (Frame*)self;
+}
+
+static void frame_free(Frame *self)
+{
+ appearance_free(self->a_unfocused_title);
+ appearance_free(self->a_focused_title);
+ appearance_free(self->a_unfocused_label);
+ appearance_free(self->a_focused_label);
+ appearance_free(self->a_unfocused_handle);
+ appearance_free(self->a_focused_handle);
+ appearance_free(self->a_icon);
+
+ XDestroyWindow(ob_display, self->window);
+
+ g_free(self);
+}
+
+void frame_show(Frame *self)
+{
+ if (!self->visible) {
+ self->visible = TRUE;
+ XMapWindow(ob_display, self->window);
+ }
+}
+
+void frame_hide(Frame *self)
+{
+ if (self->visible) {
+ self->visible = FALSE;
+ self->client->ignore_unmaps++;
+ XUnmapWindow(ob_display, self->window);
+ }
+}
+
+void frame_adjust_shape(Frame *self)
+{
+#ifdef SHAPE
+ int num;
+ XRectangle xrect[2];
+
+ if (!self->client->shaped) {
+ /* clear the shape on the frame window */
+ XShapeCombineMask(ob_display, self->window, ShapeBounding,
+ self->innersize.left,
+ self->innersize.top,
+ None, ShapeSet);
+ } else {
+ /* make the frame's shape match the clients */
+ XShapeCombineShape(ob_display, self->window, ShapeBounding,
+ self->innersize.left,
+ self->innersize.top,
+ self->client->window,
+ ShapeBounding, ShapeSet);
+
+ num = 0;
+ if (self->client->decorations & Decor_Titlebar) {
+ xrect[0].x = -theme_bevel;
+ xrect[0].y = -theme_bevel;
+ xrect[0].width = self->width + self->bwidth * 2;
+ xrect[0].height = theme_title_height +
+ self->bwidth * 2;
+ ++num;
+ }
+
+ if (self->client->decorations & Decor_Handle) {
+ xrect[1].x = -theme_bevel;
+ xrect[1].y = FRAME_HANDLE_Y(self);
+ xrect[1].width = self->width + self->bwidth * 2;
+ xrect[1].height = theme_handle_height +
+ self->bwidth * 2;
+ ++num;
+ }
+
+ XShapeCombineRectangles(ob_display, self->window,
+ ShapeBounding, 0, 0, xrect, num,
+ ShapeUnion, Unsorted);
+ }
+#endif
+}
+
+void frame_adjust_area(Frame *self, gboolean moved, gboolean resized)
+{
+ if (resized) {
+ if (self->client->decorations & Decor_Border) {
+ self->bwidth = theme_bwidth;
+ self->cbwidth = theme_cbwidth;
+ } else {
+ self->bwidth = self->cbwidth = 0;
+ }
+ STRUT_SET(self->innersize, self->cbwidth, self->cbwidth,
+ self->cbwidth, self->cbwidth);
+ self->width = self->client->area.width + self->cbwidth * 2;
+ g_assert(self->width > 0);
+
+ /* set border widths */
+ XSetWindowBorderWidth(ob_display, self->plate, self->cbwidth);
+ XSetWindowBorderWidth(ob_display, self->window, self->bwidth);
+ XSetWindowBorderWidth(ob_display, self->title, self->bwidth);
+ XSetWindowBorderWidth(ob_display, self->handle, self->bwidth);
+ XSetWindowBorderWidth(ob_display, self->lgrip, self->bwidth);
+ XSetWindowBorderWidth(ob_display, self->rgrip, self->bwidth);
+
+ /* position/size and map/unmap all the windows */
+
+ /* they all default off, they're turned on in layout_title */
+ self->icon_x = -1;
+ self->desk_x = -1;
+ self->shade_x = -1;
+ self->iconify_x = -1;
+ self->label_x = -1;
+ self->max_x = -1;
+ self->close_x = -1;
+
+ if (self->client->decorations & Decor_Titlebar) {
+ XMoveResizeWindow(ob_display, self->title,
+ -self->bwidth, -self->bwidth,
+ self->width, theme_title_height);
+ self->innersize.top += theme_title_height + self->bwidth;
+ XMapWindow(ob_display, self->title);
+
+ RECT_SET(self->a_focused_title->area, 0, 0,
+ self->width, theme_title_height);
+ RECT_SET(self->a_unfocused_title->area, 0, 0,
+ self->width, theme_title_height);
+
+ /* layout the title bar elements */
+ layout_title(self);
+ } else
+ XUnmapWindow(ob_display, self->title);
+
+ if (self->client->decorations & Decor_Handle) {
+ XMoveResizeWindow(ob_display, self->handle,
+ -self->bwidth, FRAME_HANDLE_Y(self),
+ self->width, theme_handle_height);
+ XMoveWindow(ob_display, self->lgrip,
+ -self->bwidth, -self->bwidth);
+ XMoveWindow(ob_display, self->rgrip,
+ -self->bwidth + self->width -
+ theme_grip_width, -self->bwidth);
+ self->innersize.bottom += theme_handle_height +
+ self->bwidth;
+ XMapWindow(ob_display, self->handle);
+
+ if (theme_a_focused_grip->surface.data.planar.grad ==
+ Background_ParentRelative)
+ RECT_SET(self->a_focused_handle->area, 0, 0,
+ self->width, theme_handle_height);
+ else
+ RECT_SET(self->a_focused_handle->area,
+ theme_grip_width + self->bwidth, 0,
+ self->width - (theme_grip_width + self->bwidth) * 2,
+ theme_handle_height);
+ if (theme_a_unfocused_grip->surface.data.planar.grad ==
+ Background_ParentRelative)
+ RECT_SET(self->a_unfocused_handle->area, 0, 0,
+ self->width, theme_handle_height);
+ else
+ RECT_SET(self->a_unfocused_handle->area,
+ theme_grip_width + self->bwidth, 0,
+ self->width - (theme_grip_width + self->bwidth) * 2,
+ theme_handle_height);
+
+ } else
+ XUnmapWindow(ob_display, self->handle);
+ }
+
+ if (resized) {
+ /* move and resize the plate */
+ XMoveResizeWindow(ob_display, self->plate,
+ self->innersize.left - self->cbwidth,
+ self->innersize.top - self->cbwidth,
+ self->client->area.width,
+ self->client->area.height);
+ /* when the client has StaticGravity, it likes to move around. */
+ XMoveWindow(ob_display, self->client->window, 0, 0);
+ }
+
+ if (resized) {
+ STRUT_SET(self->size,
+ self->innersize.left + self->bwidth,
+ self->innersize.top + self->bwidth,
+ self->innersize.right + self->bwidth,
+ self->innersize.bottom + self->bwidth);
+ }
+
+ /* shading can change without being moved or resized */
+ RECT_SET_SIZE(self->area,
+ self->client->area.width +
+ self->size.left + self->size.right,
+ (self->client->shaded ? theme_title_height + self->bwidth*2:
+ self->client->area.height +
+ self->size.top + self->size.bottom));
+
+ if (moved) {
+ /* find the new coordinates, done after setting the frame.size, for
+ frame_client_gravity. */
+ self->area.x = self->client->area.x;
+ self->area.y = self->client->area.y;
+ frame_client_gravity((Frame*)self,
+ &self->area.x, &self->area.y);
+ }
+
+ /* move and resize the top level frame.
+ shading can change without being moved or resized */
+ XMoveResizeWindow(ob_display, self->window,
+ self->area.x, self->area.y,
+ self->width,
+ self->area.height - self->bwidth * 2);
+
+ if (resized) {
+ framerender_frame(self);
+
+ frame_adjust_shape(self);
+ }
+}
+
+void frame_adjust_state(Frame *self)
+{
+ framerender_frame(self);
+}
+
+void frame_adjust_focus(Frame *self)
+{
+ framerender_frame(self);
+}
+
+void frame_adjust_title(Frame *self)
+{
+ framerender_frame(self);
+}
+
+void frame_adjust_icon(Frame *self)
+{
+ framerender_frame(self);
+}
+
+void frame_grab_client(Frame *self, Client *client)
+{
+ self->client = client;
+
+ /* reparent the client to the frame */
+ XReparentWindow(ob_display, client->window, self->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
+ starting up, the window is already mapped, so we'll see unmap events for
+ it. There are 2 unmap events generated that we see, one with the 'event'
+ member set the root window, and one set to the client, but both get
+ handled and need to be ignored.
+ */
+ if (ob_state == State_Starting)
+ client->ignore_unmaps += 2;
+
+ /* select the event mask on the client's parent (to receive config/map
+ req's) the ButtonPress is to catch clicks on the client border */
+ XSelectInput(ob_display, self->plate, PLATE_EVENTMASK);
+
+ /* map the client so it maps when the frame does */
+ XMapWindow(ob_display, client->window);
+
+ frame_adjust_area(self, TRUE, TRUE);
+
+ /* set all the windows for the frame in the client_map */
+ g_hash_table_insert(client_map, &self->window, client);
+ g_hash_table_insert(client_map, &self->plate, client);
+ g_hash_table_insert(client_map, &self->title, client);
+ g_hash_table_insert(client_map, &self->label, client);
+ g_hash_table_insert(client_map, &self->max, client);
+ g_hash_table_insert(client_map, &self->close, client);
+ g_hash_table_insert(client_map, &self->desk, client);
+ g_hash_table_insert(client_map, &self->shade, client);
+ g_hash_table_insert(client_map, &self->icon, client);
+ g_hash_table_insert(client_map, &self->iconify, client);
+ g_hash_table_insert(client_map, &self->handle, client);
+ g_hash_table_insert(client_map, &self->lgrip, client);
+ g_hash_table_insert(client_map, &self->rgrip, client);
+}
+
+void frame_release_client(Frame *self, Client *client)
+{
+ XEvent ev;
+
+ g_assert(self->client == client);
+
+ /* check if the app has already reparented its window away */
+ if (XCheckTypedWindowEvent(ob_display, client->window,
+ ReparentNotify, &ev)) {
+ XPutBackEvent(ob_display, &ev);
+ /* re-map the window since the unmanaging process unmaps it */
+ XMapWindow(ob_display, client->window);
+ } else {
+ /* according to the ICCCM - if the client doesn't reparent itself,
+ then we will reparent the window to root for them */
+ XReparentWindow(ob_display, client->window, ob_root,
+ client->area.x,
+ client->area.y);
+ }
+
+ /* remove all the windows for the frame from the client_map */
+ g_hash_table_remove(client_map, &self->window);
+ g_hash_table_remove(client_map, &self->plate);
+ g_hash_table_remove(client_map, &self->title);
+ g_hash_table_remove(client_map, &self->label);
+ g_hash_table_remove(client_map, &self->max);
+ g_hash_table_remove(client_map, &self->close);
+ g_hash_table_remove(client_map, &self->desk);
+ g_hash_table_remove(client_map, &self->shade);
+ g_hash_table_remove(client_map, &self->icon);
+ g_hash_table_remove(client_map, &self->iconify);
+ g_hash_table_remove(client_map, &self->handle);
+ g_hash_table_remove(client_map, &self->lgrip);
+ g_hash_table_remove(client_map, &self->rgrip);
+
+ frame_free(self);
+}
+
+static void layout_title(Frame *self)
+{
+ char *lc;
+ int x;
+ gboolean n, d, i, l, m, c, s;
+
+ n = d = i = l = m = c = s = FALSE;
+
+ /* figure out whats being shown, and the width of the label */
+ self->label_width = self->width - (theme_bevel + 1) * 2;
+ for (lc = theme_title_layout; *lc != '\0'; ++lc) {
+ switch (*lc) {
+ case 'N':
+ if (!(self->client->decorations & Decor_Icon)) break;
+ if (n) { *lc = ' '; break; } /* rm duplicates */
+ n = TRUE;
+ self->label_width -= theme_button_size + theme_bevel + 1;
+ break;
+ case 'D':
+ if (!(self->client->decorations & Decor_AllDesktops)) break;
+ if (d) { *lc = ' '; break; } /* rm duplicates */
+ d = TRUE;
+ self->label_width -= theme_button_size + theme_bevel + 1;
+ break;
+ case 'S':
+ if (!(self->client->decorations & Decor_Shade)) break;
+ if (s) { *lc = ' '; break; } /* rm duplicates */
+ s = TRUE;
+ self->label_width -= theme_button_size + theme_bevel + 1;
+ break;
+ case 'I':
+ if (!(self->client->decorations & Decor_Iconify)) break;
+ if (i) { *lc = ' '; break; } /* rm duplicates */
+ i = TRUE;
+ self->label_width -= theme_button_size + theme_bevel + 1;
+ break;
+ case 'L':
+ if (l) { *lc = ' '; break; } /* rm duplicates */
+ l = TRUE;
+ break;
+ case 'M':
+ if (!(self->client->decorations & Decor_Maximize)) break;
+ if (m) { *lc = ' '; break; } /* rm duplicates */
+ m = TRUE;
+ self->label_width -= theme_button_size + theme_bevel + 1;
+ break;
+ case 'C':
+ if (!(self->client->decorations & Decor_Close)) break;
+ if (c) { *lc = ' '; break; } /* rm duplicates */
+ c = TRUE;
+ self->label_width -= theme_button_size + theme_bevel + 1;
+ break;
+ }
+ }
+ if (self->label_width < 1) self->label_width = 1;
+
+ XResizeWindow(ob_display, self->label, self->label_width,
+ theme_label_height);
+
+ if (!n) XUnmapWindow(ob_display, self->icon);
+ if (!d) XUnmapWindow(ob_display, self->desk);
+ if (!s) XUnmapWindow(ob_display, self->shade);
+ if (!i) XUnmapWindow(ob_display, self->iconify);
+ if (!l) XUnmapWindow(ob_display, self->label);
+ if (!m) XUnmapWindow(ob_display, self->max);
+ if (!c) XUnmapWindow(ob_display, self->close);
+
+ x = theme_bevel + 1;
+ for (lc = theme_title_layout; *lc != '\0'; ++lc) {
+ switch (*lc) {
+ case 'N':
+ if (!n) break;
+ self->icon_x = x;
+ RECT_SET(self->a_icon->area, 0, 0,
+ theme_button_size, theme_button_size);
+ XMapWindow(ob_display, self->icon);
+ XMoveWindow(ob_display, self->icon, x, theme_bevel + 1);
+ x += theme_button_size + theme_bevel + 1;
+ break;
+ case 'D':
+ if (!d) break;
+ self->desk_x = x;
+ XMapWindow(ob_display, self->desk);
+ XMoveWindow(ob_display, self->desk, x, theme_bevel + 1);
+ x += theme_button_size + theme_bevel + 1;
+ break;
+ case 'S':
+ if (!s) break;
+ self->shade_x = x;
+ XMapWindow(ob_display, self->shade);
+ XMoveWindow(ob_display, self->shade, x, theme_bevel + 1);
+ x += theme_button_size + theme_bevel + 1;
+ break;
+ case 'I':
+ if (!i) break;
+ self->iconify_x = x;
+ XMapWindow(ob_display, self->iconify);
+ XMoveWindow(ob_display, self->iconify, x, theme_bevel + 1);
+ x += theme_button_size + theme_bevel + 1;
+ break;
+ case 'L':
+ if (!l) break;
+ self->label_x = x;
+ XMapWindow(ob_display, self->label);
+ XMoveWindow(ob_display, self->label, x, theme_bevel);
+ x += self->label_width + theme_bevel + 1;
+ break;
+ case 'M':
+ if (!m) break;
+ self->max_x = x;
+ XMapWindow(ob_display, self->max);
+ XMoveWindow(ob_display, self->max, x, theme_bevel + 1);
+ x += theme_button_size + theme_bevel + 1;
+ break;
+ case 'C':
+ if (!c) break;
+ self->close_x = x;
+ XMapWindow(ob_display, self->close);
+ XMoveWindow(ob_display, self->close, x, theme_bevel + 1);
+ x += theme_button_size + theme_bevel + 1;
+ break;
+ }
+ }
+
+ RECT_SET(self->a_focused_label->area, 0, 0,
+ self->label_width, theme_label_height);
+ RECT_SET(self->a_unfocused_label->area, 0, 0,
+ self->label_width, theme_label_height);
+}
Context frame_context_from_string(char *name)
{
@@ -35,6 +646,29 @@ Context frame_context_from_string(char *name)
return Context_None;
}
+Context frame_context(Frame *self, Window win)
+{
+ if (win == ob_root) return Context_Root;
+ if (self == NULL) return Context_None;
+ if (win == self->client->window) return Context_Client;
+
+ if (win == self->window) return Context_Frame;
+ if (win == self->plate) return Context_Client;
+ if (win == self->title) return Context_Titlebar;
+ if (win == self->label) return Context_Titlebar;
+ if (win == self->handle) return Context_Handle;
+ if (win == self->lgrip) return Context_BLCorner;
+ if (win == self->rgrip) return Context_BRCorner;
+ if (win == self->max) return Context_Maximize;
+ if (win == self->iconify)return Context_Iconify;
+ if (win == self->close) return Context_Close;
+ if (win == self->icon) return Context_Icon;
+ if (win == self->desk) return Context_AllDesktops;
+ if (win == self->shade) return Context_Shade;
+
+ return Context_None;
+}
+
void frame_client_gravity(Frame *self, int *x, int *y)
{
/* horizontal */
diff --git a/openbox/frame.h b/openbox/frame.h
index fb492d8c..c36e7833 100644
--- a/openbox/frame.h
+++ b/openbox/frame.h
@@ -3,6 +3,7 @@
#include "geom.h"
#include "client.h"
+#include "render/render.h"
typedef enum {
Context_None,
@@ -24,7 +25,8 @@ typedef enum {
NUM_CONTEXTS
} Context;
-Context frame_context_from_string(char *name);
+#define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
+ f->cbwidth)
typedef struct Frame {
Client *client;
@@ -35,8 +37,69 @@ typedef struct Frame {
Strut size;
Rect area;
gboolean visible;
+
+ Window title;
+ Window label;
+ Window max;
+ Window close;
+ Window desk;
+ Window shade;
+ Window icon;
+ Window iconify;
+ Window handle;
+ Window lgrip;
+ Window rgrip;
+
+ Appearance *a_unfocused_title;
+ Appearance *a_focused_title;
+ Appearance *a_unfocused_label;
+ Appearance *a_focused_label;
+ Appearance *a_icon;
+ Appearance *a_unfocused_handle;
+ Appearance *a_focused_handle;
+
+ Strut innersize;
+
+ GSList *clients;
+
+ int width; /* title and handle */
+ int label_width;
+ int icon_x; /* x-position of the window icon button */
+ int label_x; /* x-position of the window title */
+ int iconify_x; /* x-position of the window iconify button */
+ int desk_x; /* x-position of the window all-desktops button */
+ int shade_x; /* x-position of the window shade button */
+ int max_x; /* x-position of the window maximize button */
+ int close_x; /* x-position of the window close button */
+ int bwidth; /* border width */
+ int cbwidth; /* client border width */
+
+ gboolean max_press;
+ gboolean close_press;
+ gboolean desk_press;
+ gboolean shade_press;
+ gboolean iconify_press;
} Frame;
+void frame_startup();
+void frame_shutdown();
+
+Frame *frame_new();
+void frame_show(Frame *self);
+void frame_hide(Frame *self);
+void frame_adjust_shape(Frame *self);
+void frame_adjust_area(Frame *self, gboolean moved, gboolean resized);
+void frame_adjust_state(Frame *self);
+void frame_adjust_focus(Frame *self);
+void frame_adjust_title(Frame *self);
+void frame_adjust_icon(Frame *self);
+void frame_grab_client(Frame *self, Client *client);
+void frame_release_client(Frame *self, Client *client);
+
+Context frame_context_from_string(char *name);
+
+Context frame_context(Frame *self, Window win);
+
/*! Applies gravity to the client's position to find where the frame should
be positioned.
@return The proper coordinates for the frame, based on the client.
diff --git a/openbox/framerender.c b/openbox/framerender.c
new file mode 100644
index 00000000..44a6b784
--- /dev/null
+++ b/openbox/framerender.c
@@ -0,0 +1,248 @@
+#include "frame.h"
+#include "openbox.h"
+#include "screen.h"
+#include "framerender.h"
+#include "render/theme.h"
+
+static void framerender_label(Frame *self, Appearance *a);
+static void framerender_icon(Frame *self, Appearance *a);
+static void framerender_max(Frame *self, Appearance *a);
+static void framerender_iconify(Frame *self, Appearance *a);
+static void framerender_desk(Frame *self, Appearance *a);
+static void framerender_shade(Frame *self, Appearance *a);
+static void framerender_close(Frame *self, Appearance *a);
+
+void framerender_frame(Frame *self)
+{
+ if (client_focused(self->client)) {
+ XSetWindowBorder(ob_display, self->plate,
+ theme_cb_focused_color->pixel);
+ } else {
+ XSetWindowBorder(ob_display, self->plate,
+ theme_cb_unfocused_color->pixel);
+ }
+
+ if (self->client->decorations & Decor_Titlebar) {
+ Appearance *t, *l, *m, *n, *i, *d, *s, *c;
+
+ t = (client_focused(self->client) ?
+ self->a_focused_title : self->a_unfocused_title);
+ l = (client_focused(self->client) ?
+ self->a_focused_label : self->a_unfocused_label);
+ m = (client_focused(self->client) ?
+ (self->client->max_vert || self->client->max_horz ?
+ theme_a_focused_pressed_set_max :
+ (self->max_press ?
+ theme_a_focused_pressed_max : theme_a_focused_unpressed_max)) :
+ (self->client->max_vert || self->client->max_horz ?
+ theme_a_unfocused_pressed_set_max :
+ (self->max_press ?
+ theme_a_unfocused_pressed_max :
+ theme_a_unfocused_unpressed_max)));
+ n = self->a_icon;
+ i = (client_focused(self->client) ?
+ (self->iconify_press ?
+ theme_a_focused_pressed_iconify :
+ theme_a_focused_unpressed_iconify) :
+ (self->iconify_press ?
+ theme_a_unfocused_pressed_iconify :
+ theme_a_unfocused_unpressed_iconify));
+ d = (client_focused(self->client) ?
+ (self->client->desktop == DESKTOP_ALL ?
+ theme_a_focused_pressed_set_desk :
+ (self->desk_press ?
+ theme_a_focused_pressed_desk :
+ theme_a_focused_unpressed_desk)) :
+ (self->client->desktop == DESKTOP_ALL ?
+ theme_a_unfocused_pressed_set_desk :
+ (self->desk_press ?
+ theme_a_unfocused_pressed_desk :
+ theme_a_unfocused_unpressed_desk)));
+ s = (client_focused(self->client) ?
+ (self->client->shaded ?
+ theme_a_focused_pressed_set_shade :
+ (self->shade_press ?
+ theme_a_focused_pressed_shade :
+ theme_a_focused_unpressed_shade)) :
+ (self->client->shaded ?
+ theme_a_unfocused_pressed_set_shade :
+ (self->shade_press ?
+ theme_a_unfocused_pressed_shade :
+ theme_a_unfocused_unpressed_shade)));
+ c = (client_focused(self->client) ?
+ (self->close_press ?
+ theme_a_focused_pressed_close :
+ theme_a_focused_unpressed_close) :
+ (self->close_press ?
+ theme_a_unfocused_pressed_close :
+ theme_a_unfocused_unpressed_close));
+
+ paint(self->title, t);
+
+ /* set parents for any parent relative guys */
+ l->surface.data.planar.parent = t;
+ l->surface.data.planar.parentx = self->label_x;
+ l->surface.data.planar.parenty = theme_bevel;
+
+ m->surface.data.planar.parent = t;
+ m->surface.data.planar.parentx = self->max_x;
+ m->surface.data.planar.parenty = theme_bevel + 1;
+
+ n->surface.data.planar.parent = t;
+ n->surface.data.planar.parentx = self->icon_x;
+ n->surface.data.planar.parenty = theme_bevel + 1;
+
+ i->surface.data.planar.parent = t;
+ i->surface.data.planar.parentx = self->iconify_x;
+ i->surface.data.planar.parenty = theme_bevel + 1;
+
+ d->surface.data.planar.parent = t;
+ d->surface.data.planar.parentx = self->desk_x;
+ d->surface.data.planar.parenty = theme_bevel + 1;
+
+ s->surface.data.planar.parent = t;
+ s->surface.data.planar.parentx = self->shade_x;
+ s->surface.data.planar.parenty = theme_bevel + 1;
+
+ c->surface.data.planar.parent = t;
+ c->surface.data.planar.parentx = self->close_x;
+ c->surface.data.planar.parenty = theme_bevel + 1;
+
+ framerender_label(self, l);
+ framerender_max(self, m);
+ framerender_icon(self, n);
+ framerender_iconify(self, i);
+ framerender_desk(self, d);
+ framerender_shade(self, s);
+ framerender_close(self, c);
+ }
+
+ if (self->client->decorations & Decor_Handle) {
+ Appearance *h, *g;
+
+ h = (client_focused(self->client) ?
+ self->a_focused_handle : self->a_unfocused_handle);
+ g = (client_focused(self->client) ?
+ theme_a_focused_grip : theme_a_unfocused_grip);
+
+ if (g->surface.data.planar.grad == Background_ParentRelative) {
+ g->surface.data.planar.parent = h;
+ paint(self->handle, h);
+ } else
+ paint(self->handle, h);
+
+ g->surface.data.planar.parentx = 0;
+ g->surface.data.planar.parenty = 0;
+
+ paint(self->lgrip, g);
+
+ g->surface.data.planar.parentx = self->width - theme_grip_width;
+ g->surface.data.planar.parenty = 0;
+
+ paint(self->rgrip, g);
+ }
+}
+
+static void framerender_label(Frame *self, Appearance *a)
+{
+ if (self->label_x < 0) return;
+
+
+ /* set the texture's text! */
+ a->texture[0].data.text.string = self->client->title;
+ RECT_SET(a->texture[0].position, 0, 0,
+ self->label_width, theme_label_height);
+
+ paint(self->label, a);
+}
+
+static void framerender_icon(Frame *self, Appearance *a)
+{
+ if (self->icon_x < 0) return;
+
+ if (self->client->nicons) {
+ Icon *icon = client_icon(self->client,
+ theme_button_size, theme_button_size);
+ a->texture[0].type = RGBA;
+ a->texture[0].data.rgba.width = icon->width;
+ a->texture[0].data.rgba.height = icon->height;
+ a->texture[0].data.rgba.data = icon->data;
+ RECT_SET(self->a_icon->texture[0].position, 0, 0,
+ theme_button_size,theme_button_size);
+ } else
+ a->texture[0].type = NoTexture;
+
+ paint(self->icon, a);
+}
+
+static void framerender_max(Frame *self, Appearance *a)
+{
+ if (self->max_x < 0) return;
+
+ RECT_SET(a->texture[0].position, 0, 0,
+ theme_button_size, theme_button_size);
+ paint(self->max, a);
+}
+
+static void framerender_iconify(Frame *self, Appearance *a)
+{
+ if (self->iconify_x < 0) return;
+
+ RECT_SET(a->texture[0].position, 0, 0,
+ theme_button_size, theme_button_size);
+ paint(self->iconify, a);
+}
+
+static void framerender_desk(Frame *self, Appearance *a)
+{
+ if (self->desk_x < 0) return;
+
+ RECT_SET(a->texture[0].position, 0, 0,
+ theme_button_size, theme_button_size);
+ paint(self->desk, a);
+}
+
+static void framerender_shade(Frame *self, Appearance *a)
+{
+ if (self->shade_x < 0) return;
+
+ RECT_SET(a->texture[0].position, 0, 0,
+ theme_button_size, theme_button_size);
+ paint(self->shade, a);
+}
+
+static void framerender_close(Frame *self, Appearance *a)
+{
+ if (self->close_x < 0) return;
+
+ RECT_SET(a->texture[0].position, 0, 0,
+ theme_button_size, theme_button_size);
+ paint(self->close, a);
+}
+
+void framerender_popup_label(Window win, Size *sz, char *text)
+{
+ Appearance *a;
+
+ a = theme_app_hilite_label;
+ a->texture[0].data.text.string = text;
+ RECT_SET(a->area, 0, 0, sz->width, sz->height);
+ a->texture[0].position = a->area;
+
+ XSetWindowBorderWidth(ob_display, win, theme_bwidth);
+ XSetWindowBorder(ob_display, win, theme_b_color->pixel);
+
+ paint(win, a);
+}
+
+void framerender_size_popup_label(char *text, Size *sz)
+{
+ Appearance *a;
+
+ a = theme_app_hilite_label;
+ a->texture[0].data.text.string = text;
+
+ appearance_minsize(a, sz);
+ sz->width += theme_bevel * 2;
+ sz->height += theme_bevel * 2;
+}
diff --git a/openbox/framerender.h b/openbox/framerender.h
new file mode 100644
index 00000000..c02c9e7f
--- /dev/null
+++ b/openbox/framerender.h
@@ -0,0 +1,11 @@
+#ifndef __framerender_h
+#define __framerender_h
+
+#include "frame.h"
+
+void framerender_frame(Frame *self);
+
+void framerender_popup_label(Window win, Size *sz, char *text);
+void framerender_size_popup_label(char *text, Size *sz);
+
+#endif
diff --git a/openbox/openbox.c b/openbox/openbox.c
index c4784aff..afe43f27 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -6,17 +6,18 @@
#include "prop.h"
#include "screen.h"
#include "focus.h"
+#include "frame.h"
#include "extensions.h"
#include "parse.h"
#include "grab.h"
-#include "engine.h"
#include "plugin.h"
#include "timer.h"
#include "group.h"
#include "config.h"
#include "gettext.h"
-#include "../render/render.h"
-#include "../render/font.h"
+#include "render/render.h"
+#include "render/font.h"
+#include "render/theme.h"
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
@@ -64,6 +65,7 @@ int main(int argc, char **argv)
struct sigaction action;
sigset_t sigset;
char *path;
+ char *theme;
ob_state = State_Starting;
@@ -157,9 +159,9 @@ int main(int argc, char **argv)
timer_startup();
render_startup();
font_startup();
+ theme_startup();
event_startup();
grab_startup();
- engine_startup();
plugin_startup();
/* load the plugins specified in the pluginrc */
plugin_loadall();
@@ -171,9 +173,12 @@ int main(int argc, char **argv)
/* we're done with parsing now, kill it */
parse_shutdown();
- /* load the engine specified in the rc */
- engine_load();
+ /* load the theme specified in the rc file */
+ theme = theme_load("ebox"); /* woot i like this theme :) */
+ g_free(theme);
+ if (!theme) return 1;
+ frame_startup();
focus_startup();
screen_startup();
group_startup();
@@ -197,9 +202,10 @@ int main(int argc, char **argv)
group_shutdown();
screen_shutdown();
focus_shutdown();
- engine_shutdown();
+ frame_shutdown();
grab_shutdown();
event_shutdown();
+ theme_shutdown();
render_shutdown();
timer_shutdown();
config_shutdown();
diff --git a/openbox/parse.l b/openbox/parse.l
index 4dcdc2ca..64896e07 100644
--- a/openbox/parse.l
+++ b/openbox/parse.l
@@ -4,7 +4,7 @@
# include <stdlib.h>
#endif
-int yylineno = 1;
+extern int lineno;
%}
real [-0-9][0-9]*\.[0-9]+
@@ -15,9 +15,9 @@ bool ([tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[yY][eE][sS]|[nN][oO]|[oO][nN]|[oO][
%%
-^[ \t]*#.*\n /* comment */ { ++yylineno; }
+^[ \t]*#.*\n /* comment */ { ++lineno; }
^[ \t]*#.* /* comment */
-^[ \t]*\n /* empty lines */ { ++yylineno; }
+^[ \t]*\n /* empty lines */ { ++lineno; }
[ \t] /* whitespace */
{real} { yylval.real = atof(yytext); return REAL; }
{integer} { yylval.integer = atoi(yytext); return INTEGER; }
diff --git a/openbox/parse.y b/openbox/parse.y
index 125f1803..de221f9f 100644
--- a/openbox/parse.y
+++ b/openbox/parse.y
@@ -23,7 +23,7 @@ extern int yylex();
extern int yyparse();
void yyerror(char *err);
-extern int yylineno;
+extern int lineno;
extern FILE *yyin;
static char *path;
@@ -56,14 +56,14 @@ void parse_set_section(char *section);
sections:
| sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n'
- { ++yylineno; } lines
+ { ++lineno; } lines
;
lines:
| lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n'
- { ++yylineno; }
+ { ++lineno; }
| lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n'
- { ++yylineno; }
+ { ++lineno; }
;
tokens:
@@ -115,8 +115,10 @@ listtoken:
%%
+int lineno;
+
void yyerror(char *err) {
- g_message("%s:%d: %s", path, yylineno, err);
+ g_message("%s:%d: %s", path, lineno, err);
}
void parse_rc()
@@ -134,7 +136,7 @@ void parse_rc()
}
}
- yylineno = 1;
+ lineno = 1;
yyparse();
diff --git a/openbox/screen.c b/openbox/screen.c
index 49d3d22d..9f14ea8c 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -4,7 +4,6 @@
#include "screen.h"
#include "client.h"
#include "frame.h"
-#include "engine.h"
#include "focus.h"
#include "dispatch.h"
#include "../render/render.h"
@@ -287,14 +286,14 @@ void screen_set_desktop(guint num)
for (it = stacking_list; it != NULL; it = it->next) {
Client *c = it->data;
if (!c->frame->visible && client_should_show(c))
- engine_frame_show(c->frame);
+ frame_show(c->frame);
}
/* hide windows from bottom to top */
for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
Client *c = it->data;
if (c->frame->visible && !client_should_show(c))
- engine_frame_hide(c->frame);
+ frame_hide(c->frame);
}
/* focus the last focused window on the desktop, and ignore enter events
@@ -396,14 +395,14 @@ void screen_show_desktop(gboolean show)
for (it = g_list_last(stacking_list); it != NULL; it = it->prev) {
Client *client = it->data;
if (client->frame->visible && !client_should_show(client))
- engine_frame_hide(client->frame);
+ frame_hide(client->frame);
}
} else {
/* top to bottom */
for (it = stacking_list; it != NULL; it = it->next) {
Client *client = it->data;
if (!client->frame->visible && client_should_show(client))
- engine_frame_show(client->frame);
+ frame_show(client->frame);
}
}