#include "obtheme.h"
#include "obrender.h"
#include "obengine.h"
-#include "../../kernel/openbox.h"
-#include "../../kernel/extensions.h"
-#include "../../kernel/dispatch.h"
-#include "../../kernel/config.h"
-
+#include "kernel/openbox.h"
+#include "kernel/extensions.h"
+#include "kernel/dispatch.h"
+#include "kernel/config.h"
+
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+# include <sys/types.h>
+#endif
#include <X11/Xlib.h>
#include <glib.h>
#define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
-#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask)
+#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
+ ButtonPressMask | ButtonReleaseMask)
#define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
ButtonMotionMask | ExposureMask)
color_rgb *ob_s_titlebut_unfocused_color;
/* style settings - fonts */
int ob_s_winfont_height;
-int ob_s_winfont_shadow;
-int ob_s_winfont_shadow_offset;
ObFont *ob_s_winfont;
/* style settings - masks */
-pixmap_mask *ob_s_max_mask;
-pixmap_mask *ob_s_icon_mask;
-pixmap_mask *ob_s_desk_mask;
+pixmap_mask *ob_s_max_set_mask;
+pixmap_mask *ob_s_max_unset_mask;
+pixmap_mask *ob_s_iconify_mask;
+pixmap_mask *ob_s_desk_set_mask;
+pixmap_mask *ob_s_desk_unset_mask;
+pixmap_mask *ob_s_shade_set_mask;
+pixmap_mask *ob_s_shade_unset_mask;
pixmap_mask *ob_s_close_mask;
/* global appearances */
Appearance *ob_a_focused_unpressed_max;
Appearance *ob_a_focused_pressed_max;
+Appearance *ob_a_focused_pressed_set_max;
Appearance *ob_a_unfocused_unpressed_max;
Appearance *ob_a_unfocused_pressed_max;
+Appearance *ob_a_unfocused_pressed_set_max;
Appearance *ob_a_focused_unpressed_close;
Appearance *ob_a_focused_pressed_close;
Appearance *ob_a_unfocused_unpressed_close;
Appearance *ob_a_unfocused_pressed_close;
Appearance *ob_a_focused_unpressed_desk;
Appearance *ob_a_focused_pressed_desk;
+Appearance *ob_a_focused_pressed_set_desk;
Appearance *ob_a_unfocused_unpressed_desk;
Appearance *ob_a_unfocused_pressed_desk;
+Appearance *ob_a_unfocused_pressed_set_desk;
+Appearance *ob_a_focused_unpressed_shade;
+Appearance *ob_a_focused_pressed_shade;
+Appearance *ob_a_focused_pressed_set_shade;
+Appearance *ob_a_unfocused_unpressed_shade;
+Appearance *ob_a_unfocused_pressed_shade;
+Appearance *ob_a_unfocused_pressed_set_shade;
Appearance *ob_a_focused_unpressed_iconify;
Appearance *ob_a_focused_pressed_iconify;
Appearance *ob_a_unfocused_unpressed_iconify;
Appearance *ob_a_focused_handle;
Appearance *ob_a_unfocused_handle;
+Appearance *ob_app_hilite_label;
+Appearance *ob_app_unhilite_label;
+
static void layout_title(ObFrame *self);
static void mouse_event(const ObEvent *e, ObFrame *self);
gboolean startup()
{
- g_quark_from_string("none");
- g_quark_from_string("root");
- g_quark_from_string("client");
- g_quark_from_string("titlebar");
- g_quark_from_string("handle");
- g_quark_from_string("frame");
- g_quark_from_string("blcorner");
- g_quark_from_string("brcorner");
- g_quark_from_string("maximize");
- g_quark_from_string("alldesktops");
- g_quark_from_string("iconify");
- g_quark_from_string("icon");
- g_quark_from_string("close");
+ char *path;
+
+ /* create the ~/.openbox/themes/openbox dir */
+ path = g_build_filename(g_get_home_dir(), ".openbox", "themes", "openbox",
+ NULL);
+ mkdir(path, (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP |
+ S_IROTH | S_IWOTH | S_IXOTH));
+ g_free(path);
ob_s_b_color = ob_s_cb_unfocused_color = ob_s_cb_focused_color =
ob_s_title_unfocused_color = ob_s_title_focused_color =
ob_s_titlebut_unfocused_color = ob_s_titlebut_focused_color = NULL;
ob_s_winfont = NULL;
- ob_s_max_mask = ob_s_icon_mask = ob_s_desk_mask = ob_s_close_mask = NULL;
+ ob_s_max_set_mask = ob_s_max_unset_mask = NULL;
+ ob_s_desk_set_mask = ob_s_desk_unset_mask = NULL;
+ ob_s_shade_set_mask = ob_s_shade_unset_mask = NULL;
+ ob_s_iconify_mask = ob_s_close_mask = NULL;
ob_a_focused_unpressed_max = appearance_new(Surface_Planar, 1);
ob_a_focused_pressed_max = appearance_new(Surface_Planar, 1);
+ ob_a_focused_pressed_set_max = appearance_new(Surface_Planar, 1);
ob_a_unfocused_unpressed_max = appearance_new(Surface_Planar, 1);
ob_a_unfocused_pressed_max = appearance_new(Surface_Planar, 1);
+ ob_a_unfocused_pressed_set_max = appearance_new(Surface_Planar, 1);
ob_a_focused_unpressed_close = NULL;
ob_a_focused_pressed_close = NULL;
ob_a_unfocused_unpressed_close = NULL;
ob_a_unfocused_pressed_close = NULL;
ob_a_focused_unpressed_desk = NULL;
ob_a_focused_pressed_desk = NULL;
+ ob_a_focused_pressed_set_desk = NULL;
ob_a_unfocused_unpressed_desk = NULL;
ob_a_unfocused_pressed_desk = NULL;
+ ob_a_unfocused_pressed_set_desk = NULL;
+ ob_a_focused_unpressed_shade = NULL;
+ ob_a_focused_pressed_shade = NULL;
+ ob_a_focused_pressed_set_shade = NULL;
+ ob_a_unfocused_unpressed_shade = NULL;
+ ob_a_unfocused_pressed_shade = NULL;
+ ob_a_unfocused_pressed_set_shade = NULL;
ob_a_focused_unpressed_iconify = NULL;
ob_a_focused_pressed_iconify = NULL;
ob_a_unfocused_unpressed_iconify = NULL;
ob_a_icon = appearance_new(Surface_Planar, 1);
ob_a_focused_handle = appearance_new(Surface_Planar, 0);
ob_a_unfocused_handle = appearance_new(Surface_Planar, 0);
+ ob_app_hilite_label = appearance_new(Surface_Planar, 1);
+ ob_app_unhilite_label = appearance_new(Surface_Planar, 1);
if (obtheme_load()) {
RECT_SET(ob_a_focused_pressed_desk->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_focused_pressed_set_desk->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_focused_unpressed_desk->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_unfocused_pressed_desk->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_unfocused_pressed_set_desk->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_unfocused_unpressed_desk->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_focused_pressed_shade->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_focused_pressed_set_shade->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_focused_unpressed_shade->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_unfocused_pressed_shade->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_unfocused_pressed_set_shade->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_unfocused_unpressed_shade->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_focused_pressed_iconify->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_focused_unpressed_iconify->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_focused_pressed_max->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_focused_pressed_set_max->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_focused_unpressed_max->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_unfocused_pressed_max->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
+ RECT_SET(ob_a_unfocused_pressed_set_max->area, 0, 0,
+ BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_unfocused_unpressed_max->area, 0, 0,
BUTTON_SIZE, BUTTON_SIZE);
RECT_SET(ob_a_focused_pressed_close->area, 0, 0,
if (ob_s_titlebut_focused_color != NULL)
color_free(ob_s_titlebut_focused_color);
- if (ob_s_max_mask != NULL) pixmap_mask_free(ob_s_max_mask);
- if (ob_s_desk_mask != NULL) pixmap_mask_free(ob_s_desk_mask);
- if (ob_s_icon_mask != NULL) pixmap_mask_free(ob_s_icon_mask);
- if (ob_s_close_mask != NULL) pixmap_mask_free(ob_s_close_mask);
+ if (ob_s_max_set_mask != NULL)
+ pixmap_mask_free(ob_s_max_set_mask);
+ if (ob_s_max_unset_mask != NULL)
+ pixmap_mask_free(ob_s_max_unset_mask);
+ if (ob_s_desk_set_mask != NULL)
+ pixmap_mask_free(ob_s_desk_set_mask);
+ if (ob_s_desk_unset_mask != NULL)
+ pixmap_mask_free(ob_s_desk_unset_mask);
+ if (ob_s_shade_set_mask != NULL)
+ pixmap_mask_free(ob_s_shade_set_mask);
+ if (ob_s_shade_unset_mask != NULL)
+ pixmap_mask_free(ob_s_shade_unset_mask);
+ if (ob_s_iconify_mask != NULL)
+ pixmap_mask_free(ob_s_iconify_mask);
+ if (ob_s_close_mask != NULL)
+ pixmap_mask_free(ob_s_close_mask);
if (ob_s_winfont != NULL) font_close(ob_s_winfont);
appearance_free(ob_a_focused_unpressed_max);
appearance_free(ob_a_focused_pressed_max);
+ appearance_free(ob_a_focused_pressed_set_max);
appearance_free(ob_a_unfocused_unpressed_max);
appearance_free(ob_a_unfocused_pressed_max);
+ appearance_free(ob_a_unfocused_pressed_set_max);
if (ob_a_focused_unpressed_close != NULL)
appearance_free(ob_a_focused_unpressed_close);
if (ob_a_focused_pressed_close != NULL)
appearance_free(ob_a_unfocused_unpressed_desk);
if (ob_a_unfocused_pressed_desk != NULL)
appearance_free(ob_a_unfocused_pressed_desk);
+ if (ob_a_focused_unpressed_shade != NULL)
+ appearance_free(ob_a_focused_unpressed_shade);
+ if (ob_a_focused_pressed_shade != NULL)
+ appearance_free(ob_a_focused_pressed_shade);
+ if (ob_a_unfocused_unpressed_shade != NULL)
+ appearance_free(ob_a_unfocused_unpressed_shade);
+ if (ob_a_unfocused_pressed_shade != NULL)
+ appearance_free(ob_a_unfocused_pressed_shade);
if (ob_a_focused_unpressed_iconify != NULL)
appearance_free(ob_a_focused_unpressed_iconify);
if (ob_a_focused_pressed_iconify != NULL)
appearance_free(ob_a_icon);
appearance_free(ob_a_focused_handle);
appearance_free(ob_a_unfocused_handle);
+ appearance_free(ob_app_hilite_label);
+ appearance_free(ob_app_unhilite_label);
}
static Window createWindow(Window parent, unsigned long mask,
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->frame.window, mask, &attrib);
XResizeWindow(ob_display, self->icon, BUTTON_SIZE, BUTTON_SIZE);
XResizeWindow(ob_display, self->close, BUTTON_SIZE, BUTTON_SIZE);
XResizeWindow(ob_display, self->desk, BUTTON_SIZE, BUTTON_SIZE);
+ XResizeWindow(ob_display, self->shade, BUTTON_SIZE, BUTTON_SIZE);
XResizeWindow(ob_display, self->lgrip, GRIP_WIDTH, ob_s_handle_height);
XResizeWindow(ob_display, self->rgrip, GRIP_WIDTH, ob_s_handle_height);
self->a_icon = appearance_copy(ob_a_icon);
self->max_press = self->close_press = self->desk_press =
- self->iconify_press = FALSE;
+ self->iconify_press = self->shade_press = FALSE;
dispatch_register(Event_X_ButtonPress | Event_X_ButtonRelease,
(EventHandler)mouse_event, self);
/* they all default off, they're turned on in layout_title */
self->icon_x = -1;
self->desk_x = -1;
- self->icon_x = -1;
+ self->shade_x = -1;
+ self->iconify_x = -1;
self->label_x = -1;
self->max_x = -1;
self->close_x = -1;
/* layout the title bar elements */
layout_title(self);
- } else {
+ } else
XUnmapWindow(ob_display, self->title);
- /* make all the titlebar stuff not render */
- self->frame.client->decorations &= ~(Decor_Icon | Decor_Iconify |
- Decor_Maximize | Decor_Close |
- Decor_AllDesktops);
- }
if (self->frame.client->decorations & Decor_Handle) {
XMoveResizeWindow(ob_display, self->handle,
self->bwidth;
XMapWindow(ob_display, self->handle);
- if (self->a_focused_handle->surface.data.planar.grad ==
+ if (ob_a_focused_grip->surface.data.planar.grad ==
Background_ParentRelative)
RECT_SET(self->a_focused_handle->area, 0, 0,
self->width, ob_s_handle_height);
GRIP_WIDTH + self->bwidth, 0,
self->width - (GRIP_WIDTH + self->bwidth) * 2,
ob_s_handle_height);
- if (self->a_unfocused_handle->surface.data.planar.grad ==
+ if (ob_a_unfocused_grip->surface.data.planar.grad ==
Background_ParentRelative)
RECT_SET(self->a_unfocused_handle->area, 0, 0,
self->width, ob_s_handle_height);
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_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);
{
char *lc;
int x;
- gboolean n, d, i, l, m ,c;
- ConfigValue layout;
-
- n = d = i = l = m = c = FALSE;
+ gboolean n, d, i, l, m, c, s;
- if (!config_get("titlebar.layout", Config_String, &layout)) {
- layout.string = "NDLIMC";
- config_set("titlebar.layout", Config_String, layout);
- }
+ n = d = i = l = m = c = s = FALSE;
/* figure out whats being shown, and the width of the label */
self->label_width = self->width - (ob_s_bevel + 1) * 2;
- for (lc = layout.string; *lc != '\0'; ++lc) {
+ for (lc = config_engine_layout; *lc != '\0'; ++lc) {
switch (*lc) {
case 'N':
if (!(self->frame.client->decorations & Decor_Icon)) break;
d = TRUE;
self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
break;
+ case 'S':
+ if (!(self->frame.client->decorations & Decor_Shade)) break;
+ if (s) { *lc = ' '; break; } /* rm duplicates */
+ s = TRUE;
+ self->label_width -= BUTTON_SIZE + ob_s_bevel + 1;
+ break;
case 'I':
if (!(self->frame.client->decorations & Decor_Iconify)) break;
if (i) { *lc = ' '; break; } /* rm duplicates */
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 = ob_s_bevel + 1;
- for (lc = layout.string; *lc != '\0'; ++lc) {
+ for (lc = config_engine_layout; *lc != '\0'; ++lc) {
switch (*lc) {
case 'N':
if (!n) break;
XMoveWindow(ob_display, self->desk, x, ob_s_bevel + 1);
x += BUTTON_SIZE + ob_s_bevel + 1;
break;
+ case 'S':
+ if (!s) break;
+ self->shade_x = x;
+ XMapWindow(ob_display, self->shade);
+ XMoveWindow(ob_display, self->shade, x, ob_s_bevel + 1);
+ x += BUTTON_SIZE + ob_s_bevel + 1;
+ break;
case 'I':
if (!i) break;
self->iconify_x = x;
} else if (win == self->desk) {
self->desk_press = press;
obrender_frame(self);
+ } else if (win == self->shade) {
+ self->shade_press = press;
+ obrender_frame(self);
}
}
-GQuark get_context(Client *client, Window win)
+Context get_context(Client *client, Window win)
{
ObFrame *self;
- if (win == ob_root) return g_quark_try_string("root");
- if (client == NULL) return g_quark_try_string("none");
- if (win == client->window) return g_quark_try_string("client");
+ if (win == ob_root) return Context_Root;
+ if (client == NULL) return Context_None;
+ if (win == client->window) return Context_Client;
self = (ObFrame*) client->frame;
- if (win == self->frame.window) return g_quark_try_string("frame");
- if (win == self->frame.plate) return g_quark_try_string("client");
- if (win == self->title) return g_quark_try_string("titlebar");
- if (win == self->label) return g_quark_try_string("titlebar");
- if (win == self->handle) return g_quark_try_string("handle");
- if (win == self->lgrip) return g_quark_try_string("blcorner");
- if (win == self->rgrip) return g_quark_try_string("brcorner");
- if (win == self->max) return g_quark_try_string("maximize");
- if (win == self->iconify) return g_quark_try_string("iconify");
- if (win == self->close) return g_quark_try_string("close");
- if (win == self->icon) return g_quark_try_string("icon");
- if (win == self->desk) return g_quark_try_string("alldesktops");
-
- return g_quark_try_string("none");
+ if (win == self->frame.window) return Context_Frame;
+ if (win == self->frame.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;
}