summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
Diffstat (limited to 'openbox')
-rw-r--r--openbox/actions.c6
-rw-r--r--openbox/actions/execute.c5
-rw-r--r--openbox/client.c87
-rw-r--r--openbox/client_list_combined_menu.c1
-rw-r--r--openbox/client_list_menu.c1
-rw-r--r--openbox/client_menu.c1
-rw-r--r--openbox/config.c21
-rw-r--r--openbox/config.h4
-rw-r--r--openbox/dock.c22
-rw-r--r--openbox/event.c17
-rw-r--r--openbox/focus_cycle_indicator.c6
-rw-r--r--openbox/focus_cycle_popup.c1
-rw-r--r--openbox/frame.c17
-rw-r--r--openbox/frame.h10
-rw-r--r--openbox/framerender.c16
-rw-r--r--openbox/menuframe.c167
-rw-r--r--openbox/menuframe.h22
-rw-r--r--openbox/moveresize.c6
-rw-r--r--openbox/openbox.c7
-rw-r--r--openbox/place.c14
-rw-r--r--openbox/place.h7
-rw-r--r--openbox/popup.c6
-rw-r--r--openbox/screen.c7
-rw-r--r--openbox/stacking.c7
-rw-r--r--openbox/startupnotify.c55
-rw-r--r--openbox/startupnotify.h12
26 files changed, 281 insertions, 244 deletions
diff --git a/openbox/actions.c b/openbox/actions.c
index 0db82e01..10bf929a 100644
--- a/openbox/actions.c
+++ b/openbox/actions.c
@@ -337,9 +337,7 @@ void actions_client_move(ObActionsData *data, gboolean start)
else if (config_focus_follow &&
data->context != OB_FRAME_CONTEXT_CLIENT)
{
- if (!data->button && data->client && !config_focus_under_mouse)
- event_end_ignore_all_enters(ignore_start);
- else {
+ if (data->uact == OB_USER_ACTION_MOUSE_PRESS) {
struct _ObClient *c;
/* usually this is sorta redundant, but with a press action
@@ -354,5 +352,7 @@ void actions_client_move(ObActionsData *data, gboolean start)
event_enter_client(c);
}
}
+ else if (!data->button && !config_focus_under_mouse)
+ event_end_ignore_all_enters(ignore_start);
}
}
diff --git a/openbox/actions/execute.c b/openbox/actions/execute.c
index 5a747270..c534ba8b 100644
--- a/openbox/actions/execute.c
+++ b/openbox/actions/execute.c
@@ -5,6 +5,10 @@
#include "obt/paths.h"
#include "gettext.h"
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
typedef struct {
gchar *cmd;
gboolean sn;
@@ -101,6 +105,7 @@ static gboolean run_func(ObActionsData *data, gpointer options)
program = g_path_get_basename(argv[0]);
/* sets up the environment */
sn_setup_spawn_environment(program, o->sn_name, o->sn_icon,
+ o->sn_wmclass,
/* launch it on the current desktop */
screen_desktop);
}
diff --git a/openbox/client.c b/openbox/client.c
index ffbe73b0..4b0aea2f 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -200,6 +200,9 @@ void client_manage_all(void)
}
}
+ /* manage windows in reverse order from how they were originally mapped.
+ this is an attempt to manage children windows before their parents, so
+ that when the parent is mapped, it can find the child */
for (i = 0; i < nchild; ++i) {
if (children[i] == None)
continue;
@@ -288,6 +291,11 @@ void client_manage(Window window)
ob_debug("Window type: %d\n", self->type);
ob_debug("Window group: 0x%x\n", self->group?self->group->leader:0);
+ /* now we have all of the window's information so we can set this up.
+ do this before creating the frame, so it can tell that we are still
+ mapping and doesn't go applying things right away */
+ client_setup_decor_and_functions(self, FALSE);
+
/* specify that if we exit, the window should not be destroyed and
should be reparented back to root automatically */
XChangeSaveSet(obt_display, window, SetModeInsert);
@@ -308,11 +316,8 @@ void client_manage(Window window)
/* the session should get the last say though */
client_restore_session_state(self);
- /* now we have all of the window's information so we can set this up */
- client_setup_decor_and_functions(self, FALSE);
-
/* tell startup notification that this app started */
- launch_time = sn_app_started(self->startup_id, self->class);
+ launch_time = sn_app_started(self->startup_id, self->class, self->name);
/* do this after we have a frame.. it uses the frame to help determine the
WM_STATE to apply. */
@@ -797,6 +802,7 @@ void client_unmanage(ObClient *self)
g_free(self->icons[j].data);
if (self->nicons > 0)
g_free(self->icons);
+ g_free(self->startup_id);
g_free(self->wm_command);
g_free(self->title);
g_free(self->icon_title);
@@ -1832,11 +1838,11 @@ static void client_change_allowed_actions(ObClient *self)
OBT_PROP_SETA32(self->window, NET_WM_ALLOWED_ACTIONS, ATOM, actions, num);
- /* make sure the window isn't breaking any rules now
+ /* make sure the window isn't breaking any rules now
- don't check ICONIFY here. just cuz a window can't iconify doesnt mean
- it can't be iconified with its parent
- */
+ don't check ICONIFY here. just cuz a window can't iconify doesnt mean
+ it can't be iconified with its parent
+ */
if (!(self->functions & OB_CLIENT_FUNC_SHADE) && self->shaded) {
if (self->frame) client_shade(self, FALSE);
@@ -2069,11 +2075,17 @@ void client_update_strut(ObClient *self)
}
}
+/* Avoid storing icons above this size if possible */
+#define AVOID_ABOVE 64
+
void client_update_icons(ObClient *self)
{
guint num;
guint32 *data;
guint w, h, i, j;
+ guint num_seen; /* number of icons present */
+ guint num_small_seen; /* number of icons small enough present */
+ guint smallest, smallest_area;
for (i = 0; i < self->nicons; ++i)
g_free(self->icons[i].data);
@@ -2084,25 +2096,54 @@ void client_update_icons(ObClient *self)
if (OBT_PROP_GETA32(self->window, NET_WM_ICON, CARDINAL, &data, &num)) {
/* figure out how many valid icons are in here */
i = 0;
- while (num - i > 2) {
- w = data[i++];
- h = data[i++];
- i += w * h;
- if (i > num || w*h == 0) break;
- ++self->nicons;
- }
+ num_seen = num_small_seen = 0;
+ smallest = smallest_area = 0;
+ if (num > 2)
+ while (i < num) {
+ w = data[i++];
+ h = data[i++];
+ i += w * h;
+ /* watch for it being too small for the specified size, or for
+ zero sized icons. */
+ if (i > num || w == 0 || h == 0) break;
+
+ if (!smallest_area || w*h < smallest_area) {
+ smallest = num_seen;
+ smallest_area = w*h;
+ }
+ ++num_seen;
+ if (w <= AVOID_ABOVE && h <= AVOID_ABOVE)
+ ++num_small_seen;
+ }
+ if (num_small_seen > 0)
+ self->nicons = num_small_seen;
+ else if (num_seen)
+ self->nicons = 1;
self->icons = g_new(ObClientIcon, self->nicons);
/* store the icons */
i = 0;
- for (j = 0; j < self->nicons; ++j) {
+ for (j = 0; j < self->nicons;) {
guint x, y, t;
w = self->icons[j].width = data[i++];
h = self->icons[j].height = data[i++];
- if (w*h == 0) continue;
+ /* if there are some icons smaller than the threshold, we're
+ skipping all the ones above */
+ if (num_small_seen > 0) {
+ if (w > AVOID_ABOVE || h > AVOID_ABOVE) {
+ i += w*h;
+ continue;
+ }
+ }
+ /* if there were no icons smaller than the threshold, then we are
+ only taking the smallest available one we saw */
+ else if (j != smallest) {
+ i += w*h;
+ continue;
+ }
self->icons[j].data = g_new(RrPixel32, w * h);
for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) {
@@ -2117,6 +2158,8 @@ void client_update_icons(ObClient *self)
(((data[i] >> 0) & 0xff) << RrDefaultBlueOffset);
}
g_assert(i <= num);
+
+ ++j;
}
g_free(data);
@@ -2179,11 +2222,13 @@ void client_update_icon_geometry(ObClient *self)
RECT_SET(self->icon_geometry, 0, 0, 0, 0);
if (OBT_PROP_GETA32(self->window, NET_WM_ICON_GEOMETRY, CARDINAL,
- &data, &num) && num == 4)
+ &data, &num))
{
- /* don't let them set it with an area < 0 */
- RECT_SET(self->icon_geometry, data[0], data[1],
- MAX(data[2],0), MAX(data[3],0));
+ if (num == 4)
+ /* don't let them set it with an area < 0 */
+ RECT_SET(self->icon_geometry, data[0], data[1],
+ MAX(data[2],0), MAX(data[3],0));
+ g_free(data);
}
}
diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c
index f7fc36b8..c1572eaf 100644
--- a/openbox/client_list_combined_menu.c
+++ b/openbox/client_list_combined_menu.c
@@ -22,6 +22,7 @@
#include "menuframe.h"
#include "screen.h"
#include "client.h"
+#include "client_list_combined_menu.h"
#include "focus.h"
#include "config.h"
#include "gettext.h"
diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c
index 33f4b6f5..0febe2e6 100644
--- a/openbox/client_list_menu.c
+++ b/openbox/client_list_menu.c
@@ -22,6 +22,7 @@
#include "menuframe.h"
#include "screen.h"
#include "client.h"
+#include "client_list_menu.h"
#include "focus.h"
#include "config.h"
#include "gettext.h"
diff --git a/openbox/client_menu.c b/openbox/client_menu.c
index 96970352..04f50e85 100644
--- a/openbox/client_menu.c
+++ b/openbox/client_menu.c
@@ -22,6 +22,7 @@
#include "config.h"
#include "screen.h"
#include "client.h"
+#include "client_menu.h"
#include "openbox.h"
#include "frame.h"
#include "moveresize.h"
diff --git a/openbox/config.c b/openbox/config.c
index ce3649d9..eaaab536 100644
--- a/openbox/config.c
+++ b/openbox/config.c
@@ -35,9 +35,9 @@ gboolean config_focus_raise;
gboolean config_focus_last;
gboolean config_focus_under_mouse;
-ObPlacePolicy config_place_policy;
-gboolean config_place_center;
-gboolean config_place_active;
+ObPlacePolicy config_place_policy;
+gboolean config_place_center;
+ObPlaceMonitor config_place_monitor;
StrutPartial config_margins;
@@ -54,7 +54,7 @@ RrFont *config_font_menuitem;
RrFont *config_font_menutitle;
RrFont *config_font_osd;
-gint config_desktops_num;
+guint config_desktops_num;
GSList *config_desktops_names;
guint config_screen_firstdesk;
guint config_desktop_popup_time;
@@ -481,8 +481,12 @@ static void parse_placement(xmlNodePtr node, gpointer d)
config_place_policy = OB_PLACE_POLICY_MOUSE;
if ((n = obt_parse_find_node(node, "center")))
config_place_center = obt_parse_node_bool(n);
- if ((n = obt_parse_find_node(node, "active")))
- config_place_active = obt_parse_node_bool(n);
+ if ((n = obt_parse_find_node(node, "monitor"))) {
+ if (obt_parse_node_contains(n, "active"))
+ config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
+ else if (obt_parse_node_contains(n, "mouse"))
+ config_place_monitor = OB_PLACE_MONITOR_MOUSE;
+ }
}
static void parse_margins(xmlNodePtr node, gpointer d)
@@ -592,7 +596,7 @@ static void parse_desktops(xmlNodePtr node, gpointer d)
if ((n = obt_parse_find_node(node, "number"))) {
gint d = obt_parse_node_int(n);
if (d > 0)
- config_desktops_num = d;
+ config_desktops_num = (unsigned) d;
}
if ((n = obt_parse_find_node(node, "firstdesk"))) {
gint d = obt_parse_node_int(n);
@@ -870,7 +874,7 @@ void config_startup(ObtParseInst *i)
config_place_policy = OB_PLACE_POLICY_SMART;
config_place_center = TRUE;
- config_place_active = FALSE;
+ config_place_monitor = OB_PLACE_MONITOR_ANY;
obt_parse_register(i, "placement", parse_placement, NULL);
@@ -966,6 +970,7 @@ void config_shutdown(void)
RrFontClose(config_font_inactivewindow);
RrFontClose(config_font_menuitem);
RrFontClose(config_font_menutitle);
+ RrFontClose(config_font_osd);
for (it = config_desktops_names; it; it = g_slist_next(it))
g_free(it->data);
diff --git a/openbox/config.h b/openbox/config.h
index ac188e31..1a60ee0f 100644
--- a/openbox/config.h
+++ b/openbox/config.h
@@ -77,7 +77,7 @@ extern ObPlacePolicy config_place_policy;
extern gboolean config_place_center;
/*! Place windows on the active monitor (unless they are part of an application
already on another monitor) */
-extern gboolean config_place_active;
+extern ObPlaceMonitor config_place_monitor;
/*! User-specified margins around the edge of the screen(s) */
extern StrutPartial config_margins;
@@ -142,7 +142,7 @@ extern RrFont *config_font_menuitem;
extern RrFont *config_font_osd;
/*! The number of desktops */
-extern gint config_desktops_num;
+extern guint config_desktops_num;
/*! Desktop to start on, put 5 to start in the center of a 3x3 grid */
extern guint config_screen_firstdesk;
/*! Names for the desktops */
diff --git a/openbox/dock.c b/openbox/dock.c
index adf61e84..f36fca82 100644
--- a/openbox/dock.c
+++ b/openbox/dock.c
@@ -243,8 +243,10 @@ void dock_configure(void)
}
}
- dock->area.width += l + r;
- dock->area.height += t + b;
+ if (dock->dock_apps) {
+ dock->area.width += l + r;
+ dock->area.height += t + b;
+ }
hspot = l;
vspot = t;
@@ -421,11 +423,12 @@ void dock_configure(void)
if (!dock->dock_apps) {
STRUT_PARTIAL_SET(dock_strut, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0);
- } else if (config_dock_floating || config_dock_nostrut)
- {
+ }
+ else if (config_dock_floating || config_dock_nostrut) {
STRUT_PARTIAL_SET(dock_strut, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0);
- } else {
+ }
+ else {
switch (config_dock_pos) {
case OB_DIRECTION_NORTHWEST:
switch (config_dock_orient) {
@@ -523,9 +526,12 @@ void dock_configure(void)
} else
XUnmapWindow(obt_display, dock->frame);
- /* but they are useful outside of this function! */
- dock->area.width += ob_rr_theme->obwidth * 2;
- dock->area.height += ob_rr_theme->obwidth * 2;
+ /* but they are useful outside of this function! but don't add it if the
+ dock is actually not visible */
+ if (dock->dock_apps) {
+ dock->area.width += ob_rr_theme->obwidth * 2;
+ dock->area.height += ob_rr_theme->obwidth * 2;
+ }
screen_update_areas();
diff --git a/openbox/event.c b/openbox/event.c
index 8443e08c..9377214b 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -269,7 +269,8 @@ static void event_hack_mods(XEvent *e)
magic. Our X core protocol stuff won't work, so we use this to
find what the modifier state is instead. */
if (XkbGetState(obt_display, XkbUseCoreKbd, &xkb_state) == Success)
- e->xkey.state = xkb_state.compat_state;
+ e->xkey.state =
+ obt_keyboard_only_modmasks(xkb_state.compat_state);
else
#endif
{
@@ -1929,8 +1930,7 @@ void event_halt_focus_delay(void)
gulong event_start_ignore_all_enters(void)
{
- XSync(obt_display, FALSE);
- return LastKnownRequestProcessed(obt_display);
+ return NextRequest(obt_display);
}
static void event_ignore_enter_range(gulong start, gulong end)
@@ -1949,13 +1949,18 @@ static void event_ignore_enter_range(gulong start, gulong end)
r->start, r->end);
/* increment the serial so we don't ignore events we weren't meant to */
- XSync(obt_display, FALSE);
+ OBT_PROP_ERASE(screen_support_win, MOTIF_WM_HINTS);
}
void event_end_ignore_all_enters(gulong start)
{
- XSync(obt_display, FALSE);
- event_ignore_enter_range(start, LastKnownRequestProcessed(obt_display));
+ /* Use (NextRequest-1) so that we ignore up to the current serial only.
+ Inside event_ignore_enter_range, we increment the serial by one, but if
+ we ignore that serial too, then any enter events generated by mouse
+ movement will be ignored until we create some further network traffic.
+ Instead ignore up to NextRequest-1, then when we increment the serial,
+ we will be *past* the range of ignored serials */
+ event_ignore_enter_range(start, NextRequest(obt_display)-1);
}
static gboolean is_enter_focus_event_ignored(XEvent *e)
diff --git a/openbox/focus_cycle_indicator.c b/openbox/focus_cycle_indicator.c
index 79c76e2f..da5efa56 100644
--- a/openbox/focus_cycle_indicator.c
+++ b/openbox/focus_cycle_indicator.c
@@ -158,6 +158,7 @@ void focus_cycle_draw_indicator(ObClient *c)
*/
gint x, y, w, h;
gint wt, wl, wr, wb;
+ gulong ignore_start;
wt = wl = wr = wb = FOCUS_INDICATOR_WIDTH;
@@ -166,6 +167,9 @@ void focus_cycle_draw_indicator(ObClient *c)
w = c->frame->area.width;
h = wt;
+ /* kill enter events cause by this moving */
+ ignore_start = event_start_ignore_all_enters();
+
XMoveResizeWindow(obt_display, focus_indicator.top.window,
x, y, w, h);
a_focus_indicator->texture[0].data.lineart.x1 = 0;
@@ -270,6 +274,8 @@ void focus_cycle_draw_indicator(ObClient *c)
XMapWindow(obt_display, focus_indicator.right.window);
XMapWindow(obt_display, focus_indicator.bottom.window);
+ event_end_ignore_all_enters(ignore_start);
+
visible = TRUE;
}
}
diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c
index cb1af481..096f5c63 100644
--- a/openbox/focus_cycle_popup.c
+++ b/openbox/focus_cycle_popup.c
@@ -480,6 +480,7 @@ void focus_cycle_popup_hide(void)
g_free(t->text);
XDestroyWindow(obt_display, t->win);
+ g_free(t);
popup.targets = g_list_delete_link(popup.targets, popup.targets);
}
diff --git a/openbox/frame.c b/openbox/frame.c
index 5767351b..0975214c 100644
--- a/openbox/frame.c
+++ b/openbox/frame.c
@@ -214,27 +214,10 @@ static void set_theme_statics(ObFrame *self)
ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
XResizeWindow(obt_display, self->trrresize,
ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
-
- /* set up the dynamic appearances */
- self->a_unfocused_title = RrAppearanceCopy(ob_rr_theme->a_unfocused_title);
- self->a_focused_title = RrAppearanceCopy(ob_rr_theme->a_focused_title);
- self->a_unfocused_label = RrAppearanceCopy(ob_rr_theme->a_unfocused_label);
- self->a_focused_label = RrAppearanceCopy(ob_rr_theme->a_focused_label);
- self->a_unfocused_handle =
- RrAppearanceCopy(ob_rr_theme->a_unfocused_handle);
- self->a_focused_handle = RrAppearanceCopy(ob_rr_theme->a_focused_handle);
- self->a_icon = RrAppearanceCopy(ob_rr_theme->a_icon);
}
static void free_theme_statics(ObFrame *self)
{
- RrAppearanceFree(self->a_unfocused_title);
- RrAppearanceFree(self->a_focused_title);
- RrAppearanceFree(self->a_unfocused_label);
- RrAppearanceFree(self->a_focused_label);
- RrAppearanceFree(self->a_unfocused_handle);
- RrAppearanceFree(self->a_focused_handle);
- RrAppearanceFree(self->a_icon);
}
void frame_free(ObFrame *self)
diff --git a/openbox/frame.h b/openbox/frame.h
index 3e7b2c61..02be17a0 100644
--- a/openbox/frame.h
+++ b/openbox/frame.h
@@ -137,16 +137,6 @@ struct _ObFrame
Colormap colormap;
- RrAppearance *a_unfocused_title;
- RrAppearance *a_focused_title;
- RrAppearance *a_unfocused_label;
- RrAppearance *a_focused_label;
- RrAppearance *a_icon;
- RrAppearance *a_unfocused_handle;
- RrAppearance *a_focused_handle;
-
- GSList *clients;
-
gint icon_on; /* if the window icon button is on */
gint label_on; /* if the window title is on */
gint iconify_on; /* if the window iconify button is on */
diff --git a/openbox/framerender.c b/openbox/framerender.c
index 0b2363cd..87706b2b 100644
--- a/openbox/framerender.c
+++ b/openbox/framerender.c
@@ -124,10 +124,8 @@ void framerender_frame(ObFrame *self)
if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
RrAppearance *t, *l, *m, *n, *i, *d, *s, *c, *clear;
if (self->focused) {
-
- t = self->a_focused_title;
- l = self->a_focused_label;
-
+ t = ob_rr_theme->a_focused_title;
+ l = ob_rr_theme->a_focused_label;
m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
ob_rr_theme->a_disabled_focused_max :
(self->client->max_vert || self->client->max_horz ?
@@ -141,7 +139,7 @@ void framerender_frame(ObFrame *self)
(self->max_hover ?
ob_rr_theme->a_hover_focused_max :
ob_rr_theme->a_focused_unpressed_max))));
- n = self->a_icon;
+ n = ob_rr_theme->a_icon;
i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
ob_rr_theme->a_disabled_focused_iconify :
(self->iconify_press ?
@@ -183,8 +181,8 @@ void framerender_frame(ObFrame *self)
ob_rr_theme->a_hover_focused_close :
ob_rr_theme->a_focused_unpressed_close)));
} else {
- t = self->a_unfocused_title;
- l = self->a_unfocused_label;
+ t = ob_rr_theme->a_unfocused_title;
+ l = ob_rr_theme->a_unfocused_label;
m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
ob_rr_theme->a_disabled_unfocused_max :
(self->client->max_vert || self->client->max_horz ?
@@ -198,7 +196,7 @@ void framerender_frame(ObFrame *self)
(self->max_hover ?
ob_rr_theme->a_hover_unfocused_max :
ob_rr_theme->a_unfocused_unpressed_max))));
- n = self->a_icon;
+ n = ob_rr_theme->a_icon;
i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
ob_rr_theme->a_disabled_unfocused_iconify :
(self->iconify_press ?
@@ -318,7 +316,7 @@ void framerender_frame(ObFrame *self)
RrAppearance *h, *g;
h = (self->focused ?
- self->a_focused_handle : self->a_unfocused_handle);
+ ob_rr_theme->a_focused_handle : ob_rr_theme->a_unfocused_handle);
RrPaint(h, self->handle, self->width, ob_rr_theme->handle_height);
diff --git a/openbox/menuframe.c b/openbox/menuframe.c
index 83d0e718..b48b9280 100644
--- a/openbox/menuframe.c
+++ b/openbox/menuframe.c
@@ -77,7 +77,7 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client)
XSetWindowAttributes attr;
self = g_new0(ObMenuFrame, 1);
- self->type = OB_WINDOW_CLASS_MENUFRAME;
+ self->obwin.type = OB_WINDOW_CLASS_MENUFRAME;
self->menu = menu;
self->selected = NULL;
self->client = client;
@@ -92,7 +92,6 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, guint show_from, ObClient *client)
XSetWindowBorder(obt_display, self->window,
RrColorPixel(ob_rr_theme->menu_border_color));
- self->a_title = RrAppearanceCopy(ob_rr_theme->a_menu_title);
self->a_items = RrAppearanceCopy(ob_rr_theme->a_menu);
window_add(&self->window, MENUFRAME_AS_WINDOW(self));
@@ -112,10 +111,9 @@ void menu_frame_free(ObMenuFrame *self)
stacking_remove(MENUFRAME_AS_WINDOW(self));
window_remove(self->window);
- XDestroyWindow(obt_display, self->window);
-
RrAppearanceFree(self->a_items);
- RrAppearanceFree(self->a_title);
+
+ XDestroyWindow(obt_display, self->window);
g_free(self);
}
@@ -150,37 +148,6 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
XMapWindow(obt_display, self->window);
XMapWindow(obt_display, self->text);
- self->a_normal = RrAppearanceCopy(ob_rr_theme->a_menu_normal);
- self->a_selected = RrAppearanceCopy(ob_rr_theme->a_menu_selected);
- self->a_disabled = RrAppearanceCopy(ob_rr_theme->a_menu_disabled);
- self->a_disabled_selected =
- RrAppearanceCopy(ob_rr_theme->a_menu_disabled_selected);
-
- if (entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR) {
- self->a_separator = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
- self->a_separator->texture[0].type = RR_TEXTURE_LINE_ART;
- } else {
- self->a_icon = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
- self->a_icon->texture[0].type = RR_TEXTURE_RGBA;
- self->a_mask = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
- self->a_mask->texture[0].type = RR_TEXTURE_MASK;
- self->a_bullet_normal =
- RrAppearanceCopy(ob_rr_theme->a_menu_bullet_normal);
- self->a_bullet_selected =
- RrAppearanceCopy(ob_rr_theme->a_menu_bullet_selected);
- }
-
- self->a_text_normal =
- RrAppearanceCopy(ob_rr_theme->a_menu_text_normal);
- self->a_text_selected =
- RrAppearanceCopy(ob_rr_theme->a_menu_text_selected);
- self->a_text_disabled =
- RrAppearanceCopy(ob_rr_theme->a_menu_text_disabled);
- self->a_text_disabled_selected =
- RrAppearanceCopy(ob_rr_theme->a_menu_text_disabled_selected);
- self->a_text_title =
- RrAppearanceCopy(ob_rr_theme->a_menu_text_title);
-
window_add(&self->window, MENUFRAME_AS_WINDOW(self->frame));
return self;
@@ -206,22 +173,6 @@ static void menu_entry_frame_free(ObMenuEntryFrame *self)
g_hash_table_remove(menu_frame_map, &self->bullet);
}
- RrAppearanceFree(self->a_normal);
- RrAppearanceFree(self->a_selected);
- RrAppearanceFree(self->a_disabled);
- RrAppearanceFree(self->a_disabled_selected);
-
- RrAppearanceFree(self->a_separator);
- RrAppearanceFree(self->a_icon);
- RrAppearanceFree(self->a_mask);
- RrAppearanceFree(self->a_text_normal);
- RrAppearanceFree(self->a_text_selected);
- RrAppearanceFree(self->a_text_disabled);
- RrAppearanceFree(self->a_text_disabled_selected);
- RrAppearanceFree(self->a_text_title);
- RrAppearanceFree(self->a_bullet_normal);
- RrAppearanceFree(self->a_bullet_selected);
-
g_free(self);
}
}
@@ -367,18 +318,20 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
!self->entry->data.normal.enabled ?
/* disabled */
(self == self->frame->selected ?
- self->a_disabled_selected : self->a_disabled) :
+ ob_rr_theme->a_menu_disabled_selected :
+ ob_rr_theme->a_menu_disabled) :
/* enabled */
(self == self->frame->selected ?
- self->a_selected : self->a_normal));
+ ob_rr_theme->a_menu_selected :
+ ob_rr_theme->a_menu_normal));
th = ITEM_HEIGHT;
break;
case OB_MENU_ENTRY_TYPE_SEPARATOR:
if (self->entry->data.separator.label) {
- item_a = self->frame->a_title;
+ item_a = ob_rr_theme->a_menu_title;
th = ob_rr_theme->menu_title_height;
} else {
- item_a = self->a_normal;
+ item_a = ob_rr_theme->a_menu_normal;
th = SEPARATOR_HEIGHT + 2*PADDING;
}
break;
@@ -399,10 +352,12 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
!self->entry->data.normal.enabled ?
/* disabled */
(self == self->frame->selected ?
- self->a_text_disabled_selected : self->a_text_disabled) :
+ ob_rr_theme->a_menu_text_disabled_selected :
+ ob_rr_theme->a_menu_text_disabled) :
/* enabled */
(self == self->frame->selected ?
- self->a_text_selected : self->a_text_normal));
+ ob_rr_theme->a_menu_text_selected :
+ ob_rr_theme->a_menu_text_normal));
text_a->texture[0].data.text.string = self->entry->data.normal.label;
if (self->entry->data.normal.shortcut &&
(self->frame->menu->show_all_shortcuts ||
@@ -417,8 +372,8 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
break;
case OB_MENU_ENTRY_TYPE_SUBMENU:
text_a = (self == self->frame->selected ?
- self->a_text_selected :
- self->a_text_normal);
+ ob_rr_theme->a_menu_text_selected :
+ ob_rr_theme->a_menu_text_normal);
sub = self->entry->data.submenu.submenu;
text_a->texture[0].data.text.string = sub ? sub->title : "";
if (sub->shortcut && (self->frame->menu->show_all_shortcuts ||
@@ -432,9 +387,9 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
break;
case OB_MENU_ENTRY_TYPE_SEPARATOR:
if (self->entry->data.separator.label != NULL)
- text_a = self->a_text_title;
+ text_a = ob_rr_theme->a_menu_text_title;
else
- text_a = self->a_text_normal;
+ text_a = ob_rr_theme->a_menu_text_normal;
break;
}
@@ -477,20 +432,24 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
ob_rr_theme->menu_title_height -
2*ob_rr_theme->paddingy);
} else {
+ RrAppearance *clear;
+
/* unlabeled separaator */
XMoveResizeWindow(obt_display, self->text, PADDING, PADDING,
self->area.width - 2*PADDING, SEPARATOR_HEIGHT);
- self->a_separator->surface.parent = item_a;
- self->a_separator->surface.parentx = PADDING;
- self->a_separator->surface.parenty = PADDING;
- self->a_separator->texture[0].data.lineart.color =
+
+ clear = ob_rr_theme->a_clear_tex;
+ clear->texture[0].type = RR_TEXTURE_LINE_ART;
+ clear->surface.parent = item_a;
+ clear->surface.parentx = PADDING;
+ clear->surface.parenty = PADDING;
+ clear->texture[0].data.lineart.color =
text_a->texture[0].data.text.color;
- self->a_separator->texture[0].data.lineart.x1 = 2*PADDING;
- self->a_separator->texture[0].data.lineart.y1 = SEPARATOR_HEIGHT/2;
- self->a_separator->texture[0].data.lineart.x2 =
- self->area.width - 4*PADDING;
- self->a_separator->texture[0].data.lineart.y2 = SEPARATOR_HEIGHT/2;
- RrPaint(self->a_separator, self->text,
+ clear->texture[0].data.lineart.x1 = 2*PADDING;
+ clear->texture[0].data.lineart.y1 = SEPARATOR_HEIGHT/2;
+ clear->texture[0].data.lineart.x2 = self->area.width - 4*PADDING;
+ clear->texture[0].data.lineart.y2 = SEPARATOR_HEIGHT/2;
+ RrPaint(clear, self->text,
self->area.width - 2*PADDING, SEPARATOR_HEIGHT);
}
break;
@@ -499,24 +458,29 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
self->entry->data.normal.icon_data)
{
+ RrAppearance *clear;
+
XMoveResizeWindow(obt_display, self->icon,
PADDING, frame->item_margin.top,
ITEM_HEIGHT - frame->item_margin.top
- frame->item_margin.bottom,
ITEM_HEIGHT - frame->item_margin.top
- frame->item_margin.bottom);
- self->a_icon->texture[0].data.rgba.width =
+
+ clear = ob_rr_theme->a_clear_tex;
+ clear->texture[0].type = RR_TEXTURE_RGBA;
+ clear->texture[0].data.rgba.width =
self->entry->data.normal.icon_width;
- self->a_icon->texture[0].data.rgba.height =
+ clear->texture[0].data.rgba.height =
self->entry->data.normal.icon_height;
- self->a_icon->texture[0].data.rgba.alpha =
+ clear->texture[0].data.rgba.alpha =
self->entry->data.normal.icon_alpha;
- self->a_icon->texture[0].data.rgba.data =
+ clear->texture[0].data.rgba.data =
self->entry->data.normal.icon_data;
- self->a_icon->surface.parent = item_a;
- self->a_icon->surface.parentx = PADDING;
- self->a_icon->surface.parenty = frame->item_margin.top;
- RrPaint(self->a_icon, self->icon,
+ clear->surface.parent = item_a;
+ clear->surface.parentx = PADDING;
+ clear->surface.parenty = frame->item_margin.top;
+ RrPaint(clear, self->icon,
ITEM_HEIGHT - frame->item_margin.top
- frame->item_margin.bottom,
ITEM_HEIGHT - frame->item_margin.top
@@ -526,6 +490,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
self->entry->data.normal.mask)
{
RrColor *c;
+ RrAppearance *clear;
XMoveResizeWindow(obt_display, self->icon,
PADDING, frame->item_margin.top,
@@ -533,7 +498,10 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
- frame->item_margin.bottom,
ITEM_HEIGHT - frame->item_margin.top
- frame->item_margin.bottom);
- self->a_mask->texture[0].data.mask.mask =
+
+ clear = ob_rr_theme->a_clear_tex;
+ clear->texture[0].type = RR_TEXTURE_MASK;
+ clear->texture[0].data.mask.mask =
self->entry->data.normal.mask;
c = (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
@@ -546,12 +514,12 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
(self == self->frame->selected ?
self->entry->data.normal.mask_selected_color :
self->entry->data.normal.mask_normal_color));
- self->a_mask->texture[0].data.mask.color = c;
+ clear->texture[0].data.mask.color = c;
- self->a_mask->surface.parent = item_a;
- self->a_mask->surface.parentx = PADDING;
- self->a_mask->surface.parenty = frame->item_margin.top;
- RrPaint(self->a_mask, self->icon,
+ clear->surface.parent = item_a;
+ clear->surface.parentx = PADDING;
+ clear->surface.parenty = frame->item_margin.top;
+ RrPaint(clear, self->icon,
ITEM_HEIGHT - frame->item_margin.top
- frame->item_margin.bottom,
ITEM_HEIGHT - frame->item_margin.top
@@ -568,8 +536,8 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self)
ITEM_HEIGHT - 2*PADDING,
ITEM_HEIGHT - 2*PADDING);
bullet_a = (self == self->frame->selected ?
- self->a_bullet_selected :
- self->a_bullet_normal);
+ ob_rr_theme->a_menu_bullet_selected :
+ ob_rr_theme->a_menu_bullet_normal);
bullet_a->surface.parent = item_a;
bullet_a->surface.parentx =
self->frame->text_x + self->frame->text_w - ITEM_HEIGHT + PADDING;
@@ -645,31 +613,31 @@ void menu_frame_render(ObMenuFrame *self)
gint l, t, r, b;
e = self->entries->data;
- e->a_text_normal->texture[0].data.text.string = "";
- tw = RrMinWidth(e->a_text_normal);
+ ob_rr_theme->a_menu_text_normal->texture[0].data.text.string = "";
+ tw = RrMinWidth(ob_rr_theme->a_menu_text_normal);
tw += 2*PADDING;
th = ITEM_HEIGHT;
- RrMargins(e->a_normal, &l, &t, &r, &b);
+ RrMargins(ob_rr_theme->a_menu_normal, &l, &t, &r, &b);
STRUT_SET(self->item_margin,
MAX(self->item_margin.left, l),
MAX(self->item_margin.top, t),
MAX(self->item_margin.right, r),
MAX(self->item_margin.bottom, b));
- RrMargins(e->a_selected, &l, &t, &r, &b);
+ RrMargins(ob_rr_theme->a_menu_selected, &l, &t, &r, &b);
STRUT_SET(self->item_margin,
MAX(self->item_margin.left, l),
MAX(self->item_margin.top, t),
MAX(self->item_margin.right, r),
MAX(self->item_margin.bottom, b));
- RrMargins(e->a_disabled, &l, &t, &r, &b);
+ RrMargins(ob_rr_theme->a_menu_disabled, &l, &t, &r, &b);
STRUT_SET(self->item_margin,
MAX(self->item_margin.left, l),
MAX(self->item_margin.top, t),
MAX(self->item_margin.right, r),
MAX(self->item_margin.bottom, b));
- RrMargins(e->a_disabled_selected, &l, &t, &r, &b);
+ RrMargins(ob_rr_theme->a_menu_disabled_selected, &l, &t, &r, &b);
STRUT_SET(self->item_margin,
MAX(self->item_margin.left, l),
MAX(self->item_margin.top, t),
@@ -710,10 +678,12 @@ void menu_frame_render(ObMenuFrame *self)
!e->entry->data.normal.enabled ?
/* disabled */
(e == self->selected ?
- e->a_text_disabled_selected : e->a_text_disabled) :
+ ob_rr_theme->a_menu_text_disabled_selected :
+ ob_rr_theme->a_menu_text_disabled) :
/* enabled */
(e == self->selected ?
- e->a_text_selected : e->a_text_normal));
+ ob_rr_theme->a_menu_text_selected :
+ ob_rr_theme->a_menu_text_normal));
switch (e->entry->type) {
case OB_MENU_ENTRY_TYPE_NORMAL:
text_a->texture[0].data.text.string = e->entry->data.normal.label;
@@ -740,9 +710,10 @@ void menu_frame_render(ObMenuFrame *self)
break;
case OB_MENU_ENTRY_TYPE_SEPARATOR:
if (e->entry->data.separator.label != NULL) {
- e->a_text_title->texture[0].data.text.string =
+ ob_rr_theme->a_menu_text_title->texture[0].data.text.string =
e->entry->data.separator.label;
- tw = RrMinWidth(e->a_text_title) + 2*ob_rr_theme->paddingx;
+ tw = RrMinWidth(ob_rr_theme->a_menu_text_title) +
+ 2*ob_rr_theme->paddingx;
tw = MIN(tw, MAX_MENU_WIDTH);
th = ob_rr_theme->menu_title_height +
(ob_rr_theme->mbwidth - PADDING) *2;
diff --git a/openbox/menuframe.h b/openbox/menuframe.h
index ea1003de..daac34d2 100644
--- a/openbox/menuframe.h
+++ b/openbox/menuframe.h
@@ -38,7 +38,7 @@ extern GList *menu_frame_visible;
struct _ObMenuFrame
{
/* stuff to be an ObWindow */
- ObWindow type;
+ ObWindow obwin;
Window window;
struct _ObMenu *menu;
@@ -71,7 +71,9 @@ struct _ObMenuFrame
gint monitor; /* monitor on which to show the menu in xinerama */
- RrAppearance *a_title;
+ /* We make a copy of this for each menu, so that we don't have to re-render
+ the background of the entire menu each time we render an item inside it.
+ */
RrAppearance *a_items;
gboolean got_press; /* don't allow a KeyRelease event to run things in the
@@ -94,22 +96,6 @@ struct _ObMenuEntryFrame
Window icon;
Window text;
Window bullet;
-
- RrAppearance *a_normal;
- RrAppearance *a_selected;
- RrAppearance *a_disabled;
- RrAppearance *a_disabled_selected;
-
- RrAppearance *a_icon;
- RrAppearance *a_mask;
- RrAppearance *a_bullet_normal;
- RrAppearance *a_bullet_selected;
- RrAppearance *a_separator;
- RrAppearance *a_text_normal;
- RrAppearance *a_text_selected;
- RrAppearance *a_text_disabled;
- RrAppearance *a_text_disabled_selected;
- RrAppearance *a_text_title;
};
extern GHashTable *menu_frame_map;
diff --git a/openbox/moveresize.c b/openbox/moveresize.c
index 38963dfc..ddc518ad 100644
--- a/openbox/moveresize.c
+++ b/openbox/moveresize.c
@@ -256,7 +256,8 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
#ifdef SYNC
if (config_resize_redraw && !moving && obt_display_extension_sync &&
- moveresize_client->sync_request && moveresize_client->sync_counter)
+ moveresize_client->sync_request && moveresize_client->sync_counter &&
+ !moveresize_client->not_responding)
{
/* Initialize values for the resize syncing, and create an alarm for
the client's xsync counter */
@@ -371,7 +372,8 @@ static void do_resize(void)
#ifdef SYNC
if (config_resize_redraw && obt_display_extension_sync &&
- moveresize_client->sync_request && moveresize_client->sync_counter)
+ moveresize_client->sync_request && moveresize_client->sync_counter &&
+ !moveresize_client->not_responding)
{
XEvent ce;
XSyncValue val;
diff --git a/openbox/openbox.c b/openbox/openbox.c
index 6a58cca6..9ec47bc0 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -33,6 +33,7 @@
#include "focus_cycle_popup.h"
#include "moveresize.h"
#include "frame.h"
+#include "framerender.h"
#include "keyboard.h"
#include "mouse.h"
#include "menuframe.h"
@@ -177,7 +178,7 @@ gint main(gint argc, gchar **argv)
/* set the DISPLAY environment variable for any lauched children, to the
display we're using, so they open in the right place. */
- putenv(g_strdup_printf("DISPLAY=%s", DisplayString(obt_display)));
+ setenv("DISPLAY", DisplayString(obt_display), TRUE);
/* create available cursors */
cursors[OB_CURSOR_NONE] = None;
@@ -490,9 +491,7 @@ static void remove_args(gint *argc, gchar **argv, gint index, gint num)
static void parse_env()
{
/* unset this so we don't pass it on unknowingly */
- gchar *s = g_strdup("DESKTOP_STARTUP_ID");
- putenv(s);
- g_free(s);
+ unsetenv("DESKTOP_STARTUP_ID");
}
static void parse_args(gint *argc, gchar **argv)
diff --git a/openbox/place.c b/openbox/place.c
index 058bbfbe..81fb9752 100644
--- a/openbox/place.c
+++ b/openbox/place.c
@@ -108,7 +108,10 @@ static Rect **pick_head(ObClient *c)
}
}
- if (focus_client && client_normal(focus_client)) {
+ /* skip this if placing by the mouse position */
+ if (focus_client && client_normal(focus_client) &&
+ config_place_monitor != OB_PLACE_MONITOR_MOUSE)
+ {
add_choice(choice, client_monitor(focus_client));
ob_debug("placement adding choice %d for normal focused window\n",
client_monitor(focus_client));
@@ -146,7 +149,8 @@ static gboolean place_random(ObClient *client, gint *x, gint *y)
guint i;
areas = pick_head(client);
- i = config_place_active ? 0 : g_random_int_range(0, screen_num_monitors);
+ i = (config_place_monitor != OB_PLACE_MONITOR_ANY) ?
+ 0 : g_random_int_range(0, screen_num_monitors);
l = areas[i]->x;
t = areas[i]->y;
@@ -255,9 +259,9 @@ static gboolean place_nooverlap(ObClient *c, gint *x, gint *y)
/* try ignoring different things to find empty space */
for (ignore = 0; ignore < IGNORE_END && !ret; ignore++) {
/* try all monitors in order of preference, but only the first one
- if config_place_active is true */
- for (i = 0; (i < (config_place_active ? 1 : screen_num_monitors) &&
- !ret); ++i)
+ if config_place_monitor is MOUSE or ACTIVE */
+ for (i = 0; (i < (config_place_monitor != OB_PLACE_MONITOR_ANY ?
+ 1 : screen_num_monitors) && !ret); ++i)
{
GList *it;
diff --git a/openbox/place.h b/openbox/place.h
index e2f1d4e4..6a9add40 100644
--- a/openbox/place.h
+++ b/openbox/place.h
@@ -31,6 +31,13 @@ typedef enum
OB_PLACE_POLICY_MOUSE
} ObPlacePolicy;
+typedef enum
+{
+ OB_PLACE_MONITOR_ANY,
+ OB_PLACE_MONITOR_ACTIVE,
+ OB_PLACE_MONITOR_MOUSE
+} ObPlaceMonitor;
+
gboolean place_client(struct _ObClient *client, gint *x, gint *y,
struct _ObAppSettings *settings);
diff --git a/openbox/popup.c b/openbox/popup.c
index 8176b6bf..02c87848 100644
--- a/openbox/popup.c
+++ b/openbox/popup.c
@@ -256,6 +256,8 @@ void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
x=MAX(MIN(x, area->x+area->width-w),area->x);
y=MAX(MIN(y, area->y+area->height-h),area->y);
+ g_free(area);
+
if (m == screen_num_monitors) {
RECT_SET(mon, x, y, w, h);
m = screen_find_monitor(&mon);
@@ -265,6 +267,8 @@ void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
x=MAX(MIN(x, area->x+area->width-w),area->x);
y=MAX(MIN(y, area->y+area->height-h),area->y);
+
+ g_free(area);
}
/* set the windows/appearances up */
@@ -300,8 +304,6 @@ void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
popup_show_timeout(self);
}
}
-
- g_free(area);
}
void popup_hide(ObPopup *self)
diff --git a/openbox/screen.c b/openbox/screen.c
index dde0443e..9a37e686 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -391,7 +391,13 @@ void screen_startup(gboolean reconfig)
screen_num_desktops = 0;
if (OBT_PROP_GET32(obt_root(ob_screen),
NET_NUMBER_OF_DESKTOPS, CARDINAL, &d))
+ {
+ if (d != config_desktops_num) {
+ g_warning(_("Openbox is configured for %d desktops, but the current session has %d. Overriding the Openbox configuration."),
+ config_desktops_num, d);
+ }
screen_set_num_desktops(d);
+ }
/* restore from session if possible */
else if (session_num_desktops)
screen_set_num_desktops(session_num_desktops);
@@ -1284,7 +1290,6 @@ static void get_xinerama_screens(Rect **xin_areas, guint *nxin)
gint l, r, t, b;
if (ob_debug_xinerama) {
- g_print("Using fake xinerama !\n");
gint w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
gint h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));
*nxin = 2;
diff --git a/openbox/stacking.c b/openbox/stacking.c
index 6b3c955a..4d581966 100644
--- a/openbox/stacking.c
+++ b/openbox/stacking.c
@@ -24,6 +24,7 @@
#include "group.h"
#include "frame.h"
#include "window.h"
+#include "event.h"
#include "debug.h"
#include "obt/prop.h"
@@ -114,6 +115,7 @@ void stacking_temp_raise(ObWindow *window)
{
Window win[2];
GList *it;
+ gulong start;
/* don't use this for internal windows..! it would lower them.. */
g_assert(window_layer(window) < OB_STACKING_LAYER_INTERNAL);
@@ -129,7 +131,9 @@ void stacking_temp_raise(ObWindow *window)
}
win[1] = window_top(window);
+ start = event_start_ignore_all_enters();
XRestackWindows(obt_display, win, 2);
+ event_end_ignore_all_enters(start);
pause_changes = TRUE;
}
@@ -139,12 +143,15 @@ void stacking_restore(void)
Window *win;
GList *it;
gint i;
+ gulong start;
win = g_new(Window, g_list_length(stacking_list) + 1);
win[0] = screen_support_win;
for (i = 1, it = stacking_list; it; ++i, it = g_list_next(it))
win[i] = window_top(it->data);
+ start = event_start_ignore_all_enters();
XRestackWindows(obt_display, win, i);
+ event_end_ignore_all_enters(start);
g_free(win);
pause_changes = FALSE;
diff --git a/openbox/startupnotify.c b/openbox/startupnotify.c
index 1542be06..3e8799f8 100644
--- a/openbox/startupnotify.c
+++ b/openbox/startupnotify.c
@@ -21,20 +21,23 @@
#include "gettext.h"
#include "event.h"
-#include <stdlib.h>
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
#ifndef USE_LIBSN
void sn_startup(gboolean reconfig) {}
void sn_shutdown(gboolean reconfig) {}
gboolean sn_app_starting() { return FALSE; }
-Time sn_app_started(const gchar *id, const gchar *wmclass)
+Time sn_app_started(const gchar *id, const gchar *wmclass, const gchar *name)
{
return CurrentTime;
}
gboolean sn_get_desktop(gchar *id, guint *desktop) { return FALSE; }
-void sn_setup_spawn_environment(gchar *program, gchar *name,
- gchar *icon_name, gint desktop) {}
+void sn_setup_spawn_environment(const gchar *program, const gchar *name,
+ const gchar *icon_name, const gchar *wmclass,
+ gint desktop) {}
void sn_spawn_cancel() {}
#else
@@ -57,15 +60,8 @@ static void sn_event_func(SnMonitorEvent *event, gpointer data);
void sn_startup(gboolean reconfig)
{
- gchar *s;
-
if (reconfig) return;
- /* unset this so we don't pass it on unknowingly */
- s = g_strdup("DESKTOP_STARTUP_ID");
- putenv(s);
- g_free(s);
-
sn_display = sn_display_new(obt_display, NULL, NULL);
sn_context = sn_monitor_context_new(sn_display, ob_screen,
sn_event_func, NULL, NULL);
@@ -168,7 +164,7 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data)
screen_set_root_cursor();
}
-Time sn_app_started(const gchar *id, const gchar *wmclass)
+Time sn_app_started(const gchar *id, const gchar *wmclass, const gchar *name)
{
GSList *it;
Time t = CurrentTime;
@@ -179,10 +175,9 @@ Time sn_app_started(const gchar *id, const gchar *wmclass)
for (it = sn_waits; it; it = g_slist_next(it)) {
SnStartupSequence *seq = it->data;
gboolean found = FALSE;
- const gchar *seqid, *seqclass, *seqname, *seqbin;
+ const gchar *seqid, *seqclass, *seqbin;
seqid = sn_startup_sequence_get_id(seq);
seqclass = sn_startup_sequence_get_wmclass(seq);
- seqname = sn_startup_sequence_get_name(seq);
seqbin = sn_startup_sequence_get_binary_name(seq);
if (id && seqid) {
@@ -190,15 +185,21 @@ Time sn_app_started(const gchar *id, const gchar *wmclass)
accuracy */
if (!strcmp(seqid, id))
found = TRUE;
- } else {
- seqclass = sn_startup_sequence_get_wmclass(seq);
- seqname = sn_startup_sequence_get_name(seq);
- seqbin = sn_startup_sequence_get_binary_name(seq);
-
- if ((seqname && !g_ascii_strcasecmp(seqname, wmclass)) ||
- (seqbin && !g_ascii_strcasecmp(seqbin, wmclass)) ||
- (seqclass && !strcmp(seqclass, wmclass)))
- found = TRUE;
+ }
+ else if (seqclass) {
+ /* seqclass = "a string to match against the "resource name" or
+ "resource class" hints. These are WM_CLASS[0] and WM_CLASS[1]"
+ - from the startup-notification spec
+ */
+ found = (seqclass && !strcmp(seqclass, wmclass)) ||
+ (seqclass && !strcmp(seqclass, name));
+ }
+ else if (seqbin) {
+ /* Check the binary name against the class and name hints
+ as well, to help apps that don't have the class set
+ correctly */
+ found = (seqbin && !g_ascii_strcasecmp(seqbin, wmclass)) ||
+ (seqbin && !g_ascii_strcasecmp(seqbin, name));
}
if (found) {
@@ -231,8 +232,9 @@ static gboolean sn_launch_wait_timeout(gpointer data)
return FALSE; /* don't repeat */
}
-void sn_setup_spawn_environment(gchar *program, gchar *name,
- gchar *icon_name, gint desktop)
+void sn_setup_spawn_environment(const gchar *program, const gchar *name,
+ const gchar *icon_name, const gchar *wmclass,
+ gint desktop)
{
gchar *desc;
const char *id;
@@ -249,6 +251,7 @@ void sn_setup_spawn_environment(gchar *program, gchar *name,
sn_launcher_context_set_icon_name(sn_launcher, icon_name ?
icon_name : program);
sn_launcher_context_set_binary_name(sn_launcher, program);
+ if (wmclass) sn_launcher_context_set_wmclass(sn_launcher, wmclass);
if (desktop >= 0 && (unsigned) desktop < screen_num_desktops)
sn_launcher_context_set_workspace(sn_launcher, (signed) desktop);
sn_launcher_context_initiate(sn_launcher, "openbox", program,
@@ -262,7 +265,7 @@ void sn_setup_spawn_environment(gchar *program, gchar *name,
g_direct_equal,
(GDestroyNotify)sn_launcher_context_unref);
- putenv(g_strdup_printf("DESKTOP_STARTUP_ID=%s", id));
+ setenv("DESKTOP_STARTUP_ID", id, TRUE);
g_free(desc);
}
diff --git a/openbox/startupnotify.h b/openbox/startupnotify.h
index 7c28faba..758beee6 100644
--- a/openbox/startupnotify.h
+++ b/openbox/startupnotify.h
@@ -27,16 +27,20 @@ void sn_shutdown(gboolean reconfig);
gboolean sn_app_starting();
-/*! Notify that an app has started */
-Time sn_app_started(const gchar *id, const gchar *wmclass);
+/*! Notify that an app has started
+ @param wmclass the WM_CLASS[1] hint
+ @param name the WM_CLASS[0] hint
+ */
+Time sn_app_started(const gchar *id, const gchar *wmclass, const gchar *name);
/*! Get the desktop requested via the startup-notiication protocol if one
was requested */
gboolean sn_get_desktop(gchar *id, guint *desktop);
/* Get the environment to run the program in, with startup notification */
-void sn_setup_spawn_environment(gchar *program, gchar *name,
- gchar *icon_name, gint desktop);
+void sn_setup_spawn_environment(const gchar *program, const gchar *name,
+ const gchar *icon_name, const gchar *wmclass,
+ gint desktop);
/* Tell startup notification we're not actually running the program we
told it we were