summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
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);
}
}