Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge git://git.icculus.org/dana/openbox

  • Loading branch information...
commit 56639364298242a243badad7d25a9677087c044e 2 parents 72cfa62 + 5aad740
@BurntSushi authored
Showing with 299 additions and 102 deletions.
  1. +1 −0  .gitignore
  2. +6 −0 Makefile.am
  3. +1 −1  README.GIT
  4. +4 −2 configure.ac
  5. +4 −0 data/gnome-session/Makefile
  6. +6 −0 data/gnome-session/openbox-gnome-fallback.session
  7. +9 −0 data/gnome-session/openbox-gnome.session
  8. +4 −0 data/openbox.desktop
  9. +1 −1  data/rc.xml
  10. +9 −3 data/xsession/openbox-gnome-session.in
  11. +1 −1  data/xsession/openbox-kde-session.in
  12. +1 −1  doc/rc-mouse-focus.xml
  13. +26 −4 obrender/theme.c
  14. +3 −0  obrender/theme.h
  15. +1 −2  obt/keyboard.c
  16. +1 −0  obt/prop.c
  17. +1 −0  obt/prop.h
  18. +2 −0  openbox/actions/cyclewindows.c
  19. +86 −29 openbox/client.c
  20. +2 −0  openbox/client.h
  21. +15 −6 openbox/config.c
  22. +1 −0  openbox/config.h
  23. +17 −2 openbox/debug.c
  24. +2 −0  openbox/debug.h
  25. +10 −0 openbox/event.c
  26. +2 −1  openbox/frame.c
  27. +7 −3 openbox/framerender.c
  28. +2 −1  openbox/keyboard.c
  29. +1 −1  openbox/menu.c
  30. +9 −3 openbox/mouse.c
  31. +3 −3 openbox/openbox.c
  32. +56 −30 openbox/place.c
  33. +5 −8 openbox/screen.c
View
1  .gitignore
@@ -30,6 +30,7 @@ ltmain.sh
m4/*.m4
*.o
*.orig
+*.rej
*.lo
*.la
missing
View
6 Makefile.am
@@ -6,6 +6,7 @@ localedir = $(datadir)/locale
configdir = $(sysconfdir)/xdg
rcdir = $(configdir)/openbox
xsessionsdir = $(datadir)/xsessions
+gnomesessiondir = $(datadir)/gnome-session/sessions
gnomewmfilesdir = $(datadir)/gnome/wm-properties
pkgconfigdir = $(libdir)/pkgconfig
obtpubincludedir= $(includedir)/openbox/@OBT_VERSION@/obt
@@ -79,6 +80,7 @@ obrender_libobrender_la_CPPFLAGS = \
obrender_libobrender_la_LDFLAGS = \
-version-info $(RR_CURRENT):$(RR_REVISION):$(RR_AGE)
obrender_libobrender_la_LIBADD = \
+ obt/libobt.la \
$(X_LIBS) \
$(PANGO_LIBS) \
$(GLIB_LIBS) \
@@ -513,6 +515,10 @@ nodist_xsessions_DATA = \
data/xsession/openbox-gnome.desktop \
data/xsession/openbox-kde.desktop
+dist_gnomesession_DATA = \
+ data/gnome-session/openbox-gnome.session \
+ data/gnome-session/openbox-gnome-fallback.session
+
dist_noinst_DATA = \
data/rc.xsd \
data/menu.xsd \
View
2  README.GIT
@@ -3,7 +3,7 @@ To build Openbox from git you need:
A C Compiler (GNU GCC 3.2+ suggested)
-GNU Gettext 0.14.4
-GNU Autoconf 2.50+
--GNU Automake 1.9 (no more, no less)
+-GNU Automake 1.11+
-GNU Libtool
-Xlib library/headers (devel package)
-Pkg-Config
View
6 configure.ac
@@ -1,8 +1,10 @@
AC_PREREQ([2.54])
AC_INIT([openbox], [3.5.0], [http://bugzilla.icculus.org])
-AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([openbox/openbox.c])
+AM_INIT_AUTOMAKE([foreign])
+AM_SILENT_RULES([yes])
+
OB_VERSION=$PACKAGE_VERSION
AC_SUBST(OB_VERSION)
@@ -168,7 +170,7 @@ AC_ARG_ENABLE(imlib2,
[--disable-imlib2],
[disable use of Imlib2 image library for loading icons. [default=enabled]]
),
- [enable_imlib2=$enableeval],
+ [enable_imlib2=$enableval],
[enable_imlib2=yes]
)
View
4 data/gnome-session/Makefile
@@ -0,0 +1,4 @@
+all clean install:
+ $(MAKE) -C .. -$(MAKEFLAGS) $@
+
+.PHONY: all clean install
View
6 data/gnome-session/openbox-gnome-fallback.session
@@ -0,0 +1,6 @@
+[GNOME Session]
+Name=GNOME/Openbox fallback (Safe Mode)
+RequiredComponents=gnome-settings-daemon;
+RequiredProviders=windowmanager;
+DefaultProvider-windowmanager=openbox
+DesktopName=GNOME
View
9 data/gnome-session/openbox-gnome.session
@@ -0,0 +1,9 @@
+[GNOME Session]
+Name=GNOME/Openbox
+RequiredComponents=gnome-settings-daemon;
+# Try load with the gnome-panel and use the fallback if we can't load a panel
+RequiredProviders=windowmanager;panel
+DefaultProvider-windowmanager=openbox
+DefaultProvider-panel=gnome-panel
+FallbackSession=openbox-gnome-fallback
+DesktopName=GNOME
View
4 data/openbox.desktop
@@ -7,6 +7,10 @@ Icon=openbox
NoDisplay=true
# name we put on the WM spec check window
X-GNOME-WMName=Openbox
+# gnome-session autostart
X-GNOME-Autostart-Phase=WindowManager
X-GNOME-Provides=windowmanager
+# Ubuntu stuff
+X-Ubuntu-Gettext-Domain=openbox
+# back compat
X-GNOME-Autostart-Notify=true
View
2  data/rc.xml
@@ -313,7 +313,7 @@
<mouse>
<dragThreshold>1</dragThreshold>
<!-- number of pixels the mouse must move before a drag begins -->
- <doubleClickTime>200</doubleClickTime>
+ <doubleClickTime>500</doubleClickTime>
<!-- in milliseconds (1000 = 1 second) -->
<screenEdgeWarpTime>400</screenEdgeWarpTime>
<!-- Time before changing desktops when the pointer touches the edge of the
View
12 data/xsession/openbox-gnome-session.in
@@ -21,11 +21,11 @@ MINOR=$(echo $VER | cut -d . -f 2)
# run GNOME with Openbox as its window manager
if test $MAJOR -lt 2 || (test $MAJOR = 2 && test $MINOR -le 22); then
- # old gnome-session was easy to work with
+ # older gnome-session was easy to work with
export WINDOW_MANAGER="@bindir@/openbox"
exec gnome-session --choose-session=openbox-session "$@"
-else
- # new gnome-session requires openbox to be set in gconf and an
+elif test $MAJOR -lt 3; then
+ # old gnome-session requires openbox to be set in gconf and an
# openbox.desktop to be installed in the applications directory
SPATH=/desktop/gnome/session
@@ -54,6 +54,12 @@ else
# run GNOME/Openbox
exec gnome-session --default-session-key $SPATH/openbox_session "$@"
+else
+ # new gnome-session requires session file installed in
+ # /usr/share/gnome-session/sessions as well as openbox.desktop to be
+ # installed in the applications directory
+
+ exec gnome-session --session=openbox-gnome
fi
View
2  data/xsession/openbox-kde-session.in
@@ -8,7 +8,7 @@ if test -n "$1"; then
fi
# Set the prefix for the menu layout to use
-export XDG_MENU_PREFIX="kde-"
+export XDG_MENU_PREFIX="kde-4-"
# Clean up after GDM
xprop -root -remove _NET_NUMBER_OF_DESKTOPS \
View
2  doc/rc-mouse-focus.xml
@@ -226,7 +226,7 @@
<mouse>
<dragThreshold>8</dragThreshold>
<!-- number of pixels the mouse must move before a drag begins -->
- <doubleClickTime>200</doubleClickTime>
+ <doubleClickTime>500</doubleClickTime>
<!-- in milliseconds (1000 = 1 second) -->
<context name="Frame">
View
30 obrender/theme.c
@@ -259,9 +259,13 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
READ_INT("border.width", theme->fbwidth, 0, 100, 1);
READ_INT("menu.border.width", theme->mbwidth, 0, 100, theme->fbwidth);
READ_INT("osd.border.width", theme->obwidth, 0, 100, theme->fbwidth);
+ READ_INT("undecorated.border.width", theme->ubwidth, 0, 100,
+ theme->fbwidth);
READ_INT("menu.separator.width", theme->menu_sep_width, 1, 100, 1);
- READ_INT("menu.separator.padding.width", theme->menu_sep_paddingx, 0, 100, 6);
- READ_INT("menu.separator.padding.height", theme->menu_sep_paddingy, 0, 100, 3);
+ READ_INT("menu.separator.padding.width", theme->menu_sep_paddingx,
+ 0, 100, 6);
+ READ_INT("menu.separator.padding.height", theme->menu_sep_paddingy,
+ 0, 100, 3);
READ_INT("window.client.padding.width", theme->cbwidthx, 0, 100,
theme->paddingx);
READ_INT("window.client.padding.height", theme->cbwidthy, 0, 100,
@@ -270,7 +274,11 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
/* load colors */
READ_COLOR_("window.active.border.color", "border.color",
theme->frame_focused_border_color, RrColorNew(inst, 0, 0, 0));
-
+ /* undecorated focused border color inherits from frame focused border
+ color */
+ READ_COLOR("window.undecorated.active.border.color",
+ theme->frame_undecorated_focused_border_color,
+ RrColorCopy(theme->frame_focused_border_color));
/* title separator focused color inherits from focused border color */
READ_COLOR("window.active.title.separator.color",
theme->title_separator_focused_color,
@@ -281,6 +289,12 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
theme->frame_unfocused_border_color,
RrColorCopy(theme->frame_focused_border_color));
+ /* undecorated unfocused border color inherits from frame unfocused border
+ color */
+ READ_COLOR("window.undecorated.inactive.border.color",
+ theme->frame_undecorated_unfocused_border_color,
+ RrColorCopy(theme->frame_unfocused_border_color));
+
/* title separator unfocused color inherits from unfocused border color */
READ_COLOR("window.inactive.title.separator.color",
theme->title_separator_unfocused_color,
@@ -1598,7 +1612,9 @@ void RrThemeFree(RrTheme *theme)
RrColorFree(theme->menu_border_color);
RrColorFree(theme->osd_border_color);
RrColorFree(theme->frame_focused_border_color);
+ RrColorFree(theme->frame_undecorated_focused_border_color);
RrColorFree(theme->frame_unfocused_border_color);
+ RrColorFree(theme->frame_undecorated_unfocused_border_color);
RrColorFree(theme->title_separator_focused_color);
RrColorFree(theme->title_separator_unfocused_color);
RrColorFree(theme->cb_unfocused_color);
@@ -1781,6 +1797,7 @@ static gboolean read_string(XrmDatabase db, const gchar *rname, gchar **value)
if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
retvalue.addr != NULL) {
+ g_strstrip(retvalue.addr);
*value = retvalue.addr;
ret = TRUE;
}
@@ -1799,7 +1816,12 @@ static gboolean read_color(XrmDatabase db, const RrInstance *inst,
if (XrmGetResource(db, rname, rclass, &rettype, &retvalue) &&
retvalue.addr != NULL) {
- RrColor *c = RrColorParse(inst, retvalue.addr);
+ RrColor *c;
+
+ /* retvalue.addr is inside the xrdb database so we can't destroy it
+ but we can edit it in place, as g_strstrip does. */
+ g_strstrip(retvalue.addr);
+ c = RrColorParse(inst, retvalue.addr);
if (c != NULL) {
*value = c;
ret = TRUE;
View
3  obrender/theme.h
@@ -44,6 +44,7 @@ struct _RrTheme {
gint fbwidth; /*!< frame border width */
gint mbwidth; /*!< menu border width */
gint obwidth; /*!< osd border width */
+ gint ubwidth; /*!< undecorated frame border width */
gint cbwidthx;
gint cbwidthy;
gint menu_overlap_x;
@@ -66,7 +67,9 @@ struct _RrTheme {
RrColor *menu_border_color;
RrColor *osd_border_color;
RrColor *frame_focused_border_color;
+ RrColor *frame_undecorated_focused_border_color;
RrColor *frame_unfocused_border_color;
+ RrColor *frame_undecorated_unfocused_border_color;
RrColor *title_separator_focused_color;
RrColor *title_separator_unfocused_color;
RrColor *cb_focused_color;
View
3  obt/keyboard.c
@@ -389,12 +389,11 @@ gunichar obt_keyboard_keypress_to_unichar(ObtIC *ic, XEvent *ev)
KeySym obt_keyboard_keypress_to_keysym(XEvent *ev)
{
KeySym sym;
- gint r;
g_return_val_if_fail(ev->type == KeyPress, None);
sym = None;
- r = XLookupString(&ev->xkey, NULL, 0, &sym, NULL);
+ XLookupString(&ev->xkey, NULL, 0, &sym, NULL);
return sym;
}
View
1  obt/prop.c
@@ -107,6 +107,7 @@ void obt_prop_startup(void)
CREATE_(NET_WM_ICON_GEOMETRY);
CREATE_(NET_WM_PID);
CREATE_(NET_WM_ALLOWED_ACTIONS);
+ CREATE_(NET_WM_WINDOW_OPACITY);
CREATE_(NET_WM_USER_TIME);
/* CREATE_(NET_WM_USER_TIME_WINDOW); */
CREATE_(KDE_NET_WM_FRAME_STRUT);
View
1  obt/prop.h
@@ -148,6 +148,7 @@ typedef enum {
OBT_PROP_NET_WM_ICON_GEOMETRY,
OBT_PROP_NET_WM_PID,
OBT_PROP_NET_WM_ALLOWED_ACTIONS,
+ OBT_PROP_NET_WM_WINDOW_OPACITY,
OBT_PROP_NET_WM_USER_TIME,
/* OBT_PROP_NET_WM_USER_TIME_WINDOW, */
OBT_PROP_NET_FRAME_EXTENTS,
View
2  openbox/actions/cyclewindows.c
@@ -75,6 +75,8 @@ static gpointer setup_func(xmlNodePtr node,
if ((n = obt_xml_find_node(node, "dialog"))) {
if (obt_xml_node_contains(n, "none"))
o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
+ else if (obt_xml_node_contains(n, "no"))
+ o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_NONE;
else if (obt_xml_node_contains(n, "icons"))
o->dialog_mode = OB_FOCUS_CYCLE_POPUP_MODE_ICONS;
}
View
115 openbox/client.c
@@ -112,6 +112,8 @@ static gboolean client_can_steal_focus(ObClient *self,
gboolean allow_other_desktop,
gboolean request_from_user,
Time steal_time, Time launch_time);
+static void client_setup_default_decor_and_functions(ObClient *self);
+static void client_setup_decor_undecorated(ObClient *self);
void client_startup(gboolean reconfig)
{
@@ -238,6 +240,18 @@ void client_manage(Window window, ObPrompt *prompt)
that needs to be freed with g_free(). */
settings = client_get_settings_state(self);
+ /* the session should get the last say though */
+ client_restore_session_state(self);
+
+ /* the per-app settings/session may have changed the decorations for
+ the window, so we setup decorations for that here. this is a special
+ case because we want to place the window according to these decoration
+ changes.
+ we do this before setting up the frame so that it will reflect the
+ decorations of the window as it will be placed on screen.
+ */
+ client_setup_decor_undecorated(self);
+
/* specify that if we exit, the window should not be destroyed and
should be reparented back to root automatically, unless we are managing
an internal ObPrompt window */
@@ -253,8 +267,18 @@ void client_manage(Window window, ObPrompt *prompt)
time now */
grab_server(FALSE);
- /* the session should get the last say though */
- client_restore_session_state(self);
+ /* this needs to occur once we have a frame, since it sets a property on
+ the frame */
+ client_update_opacity(self);
+
+ /* don't put helper/modal windows on a different desktop if they are
+ related to the focused window. */
+ if (!screen_compare_desktops(self->desktop, screen_desktop) &&
+ focus_client && client_search_transient(focus_client, self) &&
+ (client_helper(self) || self->modal))
+ {
+ self->desktop = screen_desktop;
+ }
/* tell startup notification that this app started */
launch_time = sn_app_started(self->startup_id, self->class, self->name);
@@ -717,11 +741,13 @@ static gboolean client_can_steal_focus(ObClient *self,
/* This is focus stealing prevention */
ob_debug("Want to focus window 0x%x at time %u "
"launched at %u (last user interaction time %u) "
- "request from %s, allow other desktop: %s",
+ "request from %s, allow other desktop: %s, "
+ "desktop switch time %u",
self->window, steal_time, launch_time,
event_last_user_time,
(request_from_user ? "user" : "other"),
- (allow_other_desktop ? "yes" : "no"));
+ (allow_other_desktop ? "yes" : "no"),
+ screen_desktop_user_time);
/*
if no launch time is provided for an application, make one up.
@@ -777,18 +803,24 @@ static gboolean client_can_steal_focus(ObClient *self,
}
/* if it's on another desktop
- then if allow_other_desktop is true, we don't want to let it steal
+ and if allow_other_desktop is true, we generally let it steal focus.
+ but if it didn't come from the user, don't let it steal unless it was
+ launched before the user switched desktops.
focus, unless it was launched after we changed desktops and the request
came from the user
*/
- if (!(self->desktop == screen_desktop ||
- self->desktop == DESKTOP_ALL) &&
- (!allow_other_desktop ||
- (request_from_user && screen_desktop_user_time &&
- !event_time_after(launch_time, screen_desktop_user_time))))
- {
- steal = FALSE;
- ob_debug("Not focusing the window because its on another desktop\n");
+ if (!screen_compare_desktops(screen_desktop, self->desktop)) {
+ /* must be allowed */
+ if (!allow_other_desktop) {
+ steal = FALSE;
+ ob_debug("Not focusing the window because its on another desktop");
+ }
+ /* if we don't know when the desktop changed, but request is from an
+ application, don't let it change desktop on you */
+ else if (!request_from_user) {
+ steal = FALSE;
+ ob_debug("Not focusing the window because non-user request");
+ }
}
/* If something is focused... */
else if (focus_client) {
@@ -1156,11 +1188,8 @@ static void client_get_all(ObClient *self, gboolean real)
client_get_type_and_transientness(self);
client_update_normal_hints(self);
- /* set up the decor/functions before getting the state. the states may
- affect which functions are available, but we want to know the maximum
- decor/functions are available to this window, so we can then apply them
- in client_apply_startup_state() */
- client_setup_decor_and_functions(self, FALSE);
+ /* set up the maximum possible decor/functions */
+ client_setup_default_decor_and_functions(self);
client_get_state(self);
@@ -1648,6 +1677,16 @@ void client_update_colormap(ObClient *self, Colormap colormap)
self->colormap = colormap;
}
+void client_update_opacity(ObClient *self)
+{
+ guint32 o;
+
+ if (OBT_PROP_GET32(self->window, NET_WM_WINDOW_OPACITY, CARDINAL, &o))
+ OBT_PROP_SET32(self->frame->window, NET_WM_WINDOW_OPACITY, CARDINAL, o);
+ else
+ OBT_PROP_ERASE(self->frame->window, NET_WM_WINDOW_OPACITY);
+}
+
void client_update_normal_hints(ObClient *self)
{
XSizeHints size;
@@ -1704,7 +1743,7 @@ void client_update_normal_hints(ObClient *self)
ob_debug("Normal hints: not set");
}
-void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
+static void client_setup_default_decor_and_functions(ObClient *self)
{
/* start with everything (cept fullscreen) */
self->decorations =
@@ -1837,6 +1876,23 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
self->decorations &= ~OB_FRAME_DECOR_MAXIMIZE;
}
+}
+
+/*! Set up decor for a client based on its undecorated state. */
+static void client_setup_decor_undecorated(ObClient *self)
+{
+ /* If the user requested no decorations, then remove all the decorations,
+ except the border. But don't add a border if there wasn't one. */
+ if (self->undecorated)
+ self->decorations &= (config_theme_keepborder ?
+ OB_FRAME_DECOR_BORDER : 0);
+}
+
+void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
+{
+ client_setup_default_decor_and_functions(self);
+
+ client_setup_decor_undecorated(self);
if (self->max_horz && self->max_vert) {
/* once upon a time you couldn't resize maximized windows, that is not
@@ -1846,12 +1902,6 @@ void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
self->decorations &= ~(OB_FRAME_DECOR_HANDLE | OB_FRAME_DECOR_GRIPS);
}
- /* finally, the user can have requested no decorations, which overrides
- everything (but doesnt give it a border if it doesnt have one) */
- if (self->undecorated)
- self->decorations &= (config_theme_keepborder ?
- OB_FRAME_DECOR_BORDER : 0);
-
/* if we don't have a titlebar, then we cannot shade! */
if (!(self->decorations & OB_FRAME_DECOR_TITLEBAR))
self->functions &= ~OB_CLIENT_FUNC_SHADE;
@@ -2783,6 +2833,9 @@ static void client_apply_startup_state(ObClient *self,
if (fullscreen)
client_fullscreen(self, TRUE);
+ /* make sure client_setup_decor_and_functions() is called at least once */
+ client_setup_decor_and_functions(self, FALSE);
+
/* if the window hasn't been configured yet, then do so now, in fact the
x,y,w,h may _not_ be the same as the area rect, which can end up
meaning that the client isn't properly moved/resized by the fullscreen
@@ -2877,10 +2930,11 @@ void client_try_configure(ObClient *self, gint *x, gint *y, gint *w, gint *h,
/* cap any X windows at the size of an unsigned short */
*w = MIN(*w,
- G_MAXUSHORT - self->frame->size.left - self->frame->size.right);
+ (gint)G_MAXUSHORT
+ - self->frame->size.left - self->frame->size.right);
*h = MIN(*h,
- G_MAXUSHORT - self->frame->size.top - self->frame->size.bottom);
-
+ (gint)G_MAXUSHORT
+ - self->frame->size.top - self->frame->size.bottom);
/* gets the frame's position */
frame_client_gravity(self->frame, x, y);
@@ -3920,6 +3974,9 @@ gboolean client_focus(ObClient *self)
return FALSE;
}
+ /* if we have helper windows they should be there with the window */
+ client_bring_helper_windows(self);
+
ob_debug_type(OB_DEBUG_FOCUS,
"Focusing client \"%s\" (0x%x) at time %u",
self->title, self->window, event_time());
@@ -4012,7 +4069,7 @@ static void client_bring_windows_recursive(ObClient *self,
if (((helpers && client_helper(self)) ||
(modals && self->modal)) &&
- ((self->desktop != desktop && self->desktop != DESKTOP_ALL) ||
+ (!screen_compare_desktops(self->desktop, desktop) ||
(iconic && self->iconic)))
{
if (iconic && self->iconic)
View
2  openbox/client.h
@@ -616,6 +616,8 @@ void client_update_sync_request_counter(ObClient *self);
#endif
/*! Updates the window's colormap */
void client_update_colormap(ObClient *self, Colormap colormap);
+/*! Updates the requested opacity for the window from the client. */
+void client_update_opacity(ObClient *self);
/*! Updates the WMNormalHints and adjusts things if they change */
void client_update_normal_hints(ObClient *self);
View
21 openbox/config.c
@@ -111,6 +111,7 @@ ObAppSettings* config_create_app_settings(void)
settings->type = -1;
settings->decor = -1;
settings->shade = -1;
+ settings->monitor_type = OB_PLACE_MONITOR_ANY;
settings->monitor = -1;
settings->focus = -1;
settings->desktop = 0;
@@ -135,6 +136,7 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
copy_if(type, (ObClientType)-1);
copy_if(decor, -1);
copy_if(shade, -1);
+ copy_if(monitor_type, OB_PLACE_MONITOR_ANY);
copy_if(monitor, -1);
copy_if(focus, -1);
copy_if(desktop, 0);
@@ -200,8 +202,8 @@ void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
/* Manages settings for individual applications.
Some notes: monitor is the screen number in a multi monitor
- (Xinerama) setup (starting from 0) or mouse, meaning the
- monitor the pointer is on. Default: mouse.
+ (Xinerama) setup (starting from 0), or mouse: the monitor the pointer
+ is on, active: the active monitor, primary: the primary monitor.
Layer can be three values, above (Always on top), below
(Always on bottom) and everything else (normal behaviour).
Positions can be an integer value or center, which will
@@ -289,12 +291,19 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d)
settings->pos_given = TRUE;
}
- if (settings->pos_given &&
- (c = obt_xml_find_node(n->children, "monitor")))
+ /* monitor can be set without setting x or y */
+ if ((c = obt_xml_find_node(n->children, "monitor")))
if (!obt_xml_node_contains(c, "default")) {
gchar *s = obt_xml_node_string(c);
if (!g_ascii_strcasecmp(s, "mouse"))
- settings->monitor = 0;
+ settings->monitor_type =
+ OB_PLACE_MONITOR_MOUSE;
+ else if (!g_ascii_strcasecmp(s, "active"))
+ settings->monitor_type =
+ OB_PLACE_MONITOR_ACTIVE;
+ else if (!g_ascii_strcasecmp(s, "primary"))
+ settings->monitor_type =
+ OB_PLACE_MONITOR_PRIMARY;
else
settings->monitor = obt_xml_node_int(c);
g_free(s);
@@ -1070,7 +1079,7 @@ void config_startup(ObtXmlInst *i)
obt_xml_register(i, "keyboard", parse_keyboard, NULL);
config_mouse_threshold = 8;
- config_mouse_dclicktime = 200;
+ config_mouse_dclicktime = 500;
config_mouse_screenedgetime = 400;
config_mouse_screenedgewarp = FALSE;
View
1  openbox/config.h
@@ -49,6 +49,7 @@ struct _ObAppSettings
gint shade;
gint decor;
gint focus;
+ ObPlaceMonitor monitor_type;
gint monitor;
gint iconic;
gint skip_pager;
View
19 openbox/debug.c
@@ -38,6 +38,8 @@ static guint rr_handler_id = 0;
static guint obt_handler_id = 0;
static guint ob_handler_id = 0;
static guint ob_handler_prompt_id = 0;
+static GList *prompt_queue = NULL;
+static gboolean allow_prompts = TRUE;
static void log_handler(const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data);
@@ -134,8 +136,8 @@ static void log_handler(const gchar *log_domain, GLogLevelFlags log_level,
static void prompt_handler(const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer data)
{
- if (ob_state() == OB_STATE_RUNNING)
- prompt_show_message(message, "Openbox", _("Close"));
+ if (ob_state() == OB_STATE_RUNNING && allow_prompts)
+ prompt_queue = g_list_prepend(prompt_queue, g_strdup(message));
else
log_handler(log_domain, log_level, message, data);
}
@@ -184,3 +186,16 @@ void ob_debug_type(ObDebugType type, const gchar *a, ...)
log_argv(type, a, vl);
va_end(vl);
}
+
+void ob_debug_show_prompts(void)
+{
+ if (prompt_queue) {
+ allow_prompts = FALSE; /* avoid recursive prompts */
+ while (prompt_queue) {
+ prompt_show_message(prompt_queue->data, "Openbox", _("Close"));
+ g_free(prompt_queue->data);
+ prompt_queue = g_list_delete_link(prompt_queue, prompt_queue);
+ }
+ allow_prompts = TRUE;
+ }
+}
View
2  openbox/debug.h
@@ -38,4 +38,6 @@ void ob_debug_type(ObDebugType type, const gchar *a, ...);
void ob_debug_enable(ObDebugType type, gboolean enable);
+void ob_debug_show_prompts(void);
+
#endif
View
10 openbox/event.c
@@ -700,6 +700,8 @@ static void event_process(const XEvent *ec, gpointer data)
static guint pressed = 0;
static Window pressed_win = None;
+ event_sourcetime = event_curtime;
+
/* If the button press was on some non-root window, or was physically
on the root window... */
if (window != obt_root(ob_screen) ||
@@ -726,12 +728,17 @@ static void event_process(const XEvent *ec, gpointer data)
else if (e->type == KeyPress || e->type == KeyRelease ||
e->type == MotionNotify)
{
+ event_sourcetime = event_curtime;
+
used = event_handle_user_input(client, e);
if (prompt && !used)
used = event_handle_prompt(prompt, e);
}
+ /* show any debug prompts that are queued */
+ ob_debug_show_prompts();
+
/* if something happens and it's not from an XEvent, then we don't know
the time, so clear it here until the next event is handled */
event_curtime = event_sourcetime = CurrentTime;
@@ -1674,6 +1681,9 @@ static void event_handle_client(ObClient *client, XEvent *e)
event_last_user_time = t;
}
}
+ else if (msgtype == OBT_PROP_ATOM(NET_WM_WINDOW_OPACITY)) {
+ client_update_opacity(client);
+ }
#ifdef SYNC
else if (msgtype == OBT_PROP_ATOM(NET_WM_SYNC_REQUEST_COUNTER)) {
/* if they are resizing right now this would cause weird behaviour.
View
3  openbox/frame.c
@@ -348,7 +348,8 @@ void frame_adjust_area(ObFrame *self, gboolean moved,
self->shaded = self->client->shaded;
if (self->decorations & OB_FRAME_DECOR_BORDER)
- self->bwidth = ob_rr_theme->fbwidth;
+ self->bwidth = self->client->undecorated ?
+ ob_rr_theme->ubwidth : ob_rr_theme->fbwidth;
else
self->bwidth = 0;
View
10 openbox/framerender.c
@@ -68,9 +68,13 @@ void framerender_frame(ObFrame *self)
XSetWindowBackground(obt_display, self->innerbrb, px);
XClearWindow(obt_display, self->innerbrb);
- px = (self->focused ?
- RrColorPixel(ob_rr_theme->frame_focused_border_color) :
- RrColorPixel(ob_rr_theme->frame_unfocused_border_color));
+ px = RrColorPixel(self->focused ?
+ (self->client->undecorated ?
+ ob_rr_theme->frame_undecorated_focused_border_color :
+ ob_rr_theme->frame_focused_border_color) :
+ (self->client->undecorated ?
+ ob_rr_theme->frame_undecorated_unfocused_border_color :
+ ob_rr_theme->frame_unfocused_border_color));
XSetWindowBackground(obt_display, self->left, px);
XClearWindow(obt_display, self->left);
View
3  openbox/keyboard.c
@@ -313,7 +313,8 @@ void keyboard_rebind(void)
old = keyboard_firstnode;
keyboard_firstnode = NULL;
- node_rebind(old);
+ if (old)
+ node_rebind(old);
tree_destroy(old);
set_curpos(NULL);
View
2  openbox/menu.c
@@ -287,7 +287,7 @@ static void parse_menu_item(xmlNodePtr node, gpointer data)
ObActionsAct *action = actions_parse(c);
if (action)
acts = g_slist_append(acts, action);
- c = obt_xml_find_node(node->next, "action");
+ c = obt_xml_find_node(c->next, "action");
}
e = menu_add_normal(state->parent, -1, label, acts, TRUE);
View
12 openbox/mouse.c
@@ -211,7 +211,7 @@ gboolean mouse_event(ObClient *client, XEvent *e)
static Time ltime;
static guint button = 0, state = 0, lbutton = 0;
static Window lwindow = None;
- static gint px, py, pwx = -1, pwy = -1;
+ static gint px, py, pwx = -1, pwy = -1, lx = -10, ly = -10;
gboolean used = FALSE;
ObFrameContext context;
@@ -290,18 +290,24 @@ gboolean mouse_event(ObClient *client, XEvent *e)
if (e->xbutton.x >= (signed)-b &&
e->xbutton.y >= (signed)-b &&
e->xbutton.x < (signed)(w+b) &&
- e->xbutton.y < (signed)(h+b)) {
+ e->xbutton.y < (signed)(h+b))
+ {
click = TRUE;
/* double clicks happen if there were 2 in a row! */
if (lbutton == button &&
lwindow == e->xbutton.window &&
e->xbutton.time - config_mouse_dclicktime <=
- ltime) {
+ ltime &&
+ ABS(e->xbutton.x - lx) < 8 &&
+ ABS(e->xbutton.y - ly) < 8)
+ {
dclick = TRUE;
lbutton = 0;
} else {
lbutton = button;
lwindow = e->xbutton.window;
+ lx = e->xbutton.x;
+ ly = e->xbutton.y;
}
} else {
lbutton = 0;
View
6 openbox/openbox.c
@@ -515,9 +515,9 @@ static void print_version(void)
{
g_print("Openbox %s\n", PACKAGE_VERSION);
g_print(_("Copyright (c)"));
- g_print(" 2008 Mikael Magnusson\n");
+ g_print(" 2008-2011 Mikael Magnusson\n");
g_print(_("Copyright (c)"));
- g_print(" 2003-2006 Dana Jansens\n\n");
+ g_print(" 2003-2011 Dana Jansens\n\n");
g_print("This program comes with ABSOLUTELY NO WARRANTY.\n");
g_print("This is free software, and you are welcome to redistribute it\n");
g_print("under certain conditions. See the file COPYING for details.\n\n");
@@ -576,7 +576,7 @@ static void run_startup_cmd(void)
G_SPAWN_SEARCH_PATH |
G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, NULL, &e);
- if (!g_shell_parse_argv(startup_cmd, NULL, &argv, &e)) {
+ if (!ok) {
g_message("Error launching startup command: %s",
e->message);
g_error_free(e);
View
86 openbox/place.c
@@ -37,27 +37,29 @@ static Rect *pick_pointer_head(ObClient *c)
When a window is being placed in the FOREGROUND, use a monitor chosen in
the following order:
- 1. same monitor as parent
- 2. primary monitor if placement=PRIMARY
+ 1. per-app settings
+ 2. same monitor as parent
+ 3. primary monitor if placement=PRIMARY
active monitor if placement=ACTIVE
pointer monitor if placement=MOUSE
- 3. primary monitor
- 4. other monitors where the window has group members on the same desktop
- 5. other monitors where the window has group members on other desktops
- 6. other monitors
+ 4. primary monitor
+ 5. other monitors where the window has group members on the same desktop
+ 6. other monitors where the window has group members on other desktops
+ 7. other monitors
When a window is being placed in the BACKGROUND, use a monitor chosen in the
following order:
- 1. same monitor as parent
- 2. other monitors where the window has group members on the same desktop
- 2a. primary monitor in this set
- 2b. other monitors in this set
- 3. other monitors where the window has group members on other desktops
+ 1. per-app settings
+ 2. same monitor as parent
+ 3. other monitors where the window has group members on the same desktop
3a. primary monitor in this set
3b. other monitors in this set
- 4. other monitors
+ 4. other monitors where the window has group members on other desktops
4a. primary monitor in this set
4b. other monitors in this set
+ 5. other monitors
+ 5a. primary monitor in this set
+ 5b. other monitors in this set
*/
/*! One for each possible head, used to sort them in order of precedence. */
@@ -73,6 +75,7 @@ enum {
HEAD_PRIMARY = 1 << 2, /* primary monitor */
HEAD_GROUP_DESK = 1 << 3, /* has a group member on the same desktop */
HEAD_GROUP = 1 << 4, /* has a group member on another desktop */
+ HEAD_PERAPP = 1 << 5, /* chosen by per-app settings */
};
gint cmp_foreground(const void *a, const void *b)
@@ -83,6 +86,10 @@ gint cmp_foreground(const void *a, const void *b)
if (h1->monitor == h2->monitor) return 0;
+ if (h1->flags & HEAD_PERAPP) --i;
+ if (h2->flags & HEAD_PERAPP) ++i;
+ if (i) return i;
+
if (h1->flags & HEAD_PARENT) --i;
if (h2->flags & HEAD_PARENT) ++i;
if (i) return i;
@@ -114,6 +121,10 @@ gint cmp_background(const void *a, const void *b)
if (h1->monitor == h2->monitor) return 0;
+ if (h1->flags & HEAD_PERAPP) --i;
+ if (h2->flags & HEAD_PERAPP) ++i;
+ if (i) return i;
+
if (h1->flags & HEAD_PARENT) --i;
if (h2->flags & HEAD_PARENT) ++i;
if (i) return i;
@@ -144,7 +155,8 @@ gint cmp_background(const void *a, const void *b)
}
/*! Pick a monitor to place a window on. */
-static Rect *pick_head(ObClient *c, gboolean foreground)
+static Rect *pick_head(ObClient *c, gboolean foreground,
+ ObAppSettings *settings)
{
Rect *area;
ObPlaceHead *choice;
@@ -180,6 +192,33 @@ static Rect *pick_head(ObClient *c, gboolean foreground)
choice[i].flags |= HEAD_PRIMARY;
if (config_place_monitor == OB_PLACE_MONITOR_PRIMARY)
choice[i].flags |= HEAD_PLACED;
+ if (settings &&
+ settings->monitor_type == OB_PLACE_MONITOR_PRIMARY)
+ choice[i].flags |= HEAD_PERAPP;
+ }
+
+ i = screen_monitor_active();
+ if (i < screen_num_monitors) {
+ if (config_place_monitor == OB_PLACE_MONITOR_ACTIVE)
+ choice[i].flags |= HEAD_PLACED;
+ if (settings &&
+ settings->monitor_type == OB_PLACE_MONITOR_ACTIVE)
+ choice[i].flags |= HEAD_PERAPP;
+ }
+
+ i = screen_monitor_pointer();
+ if (i < screen_num_monitors) {
+ if (config_place_monitor == OB_PLACE_MONITOR_MOUSE)
+ choice[i].flags |= HEAD_PLACED;
+ if (settings &&
+ settings->monitor_type == OB_PLACE_MONITOR_MOUSE)
+ choice[i].flags |= HEAD_PERAPP;
+ }
+
+ if (settings) {
+ i = settings->monitor - 1;
+ if (i < screen_num_monitors)
+ choice[i].flags |= HEAD_PERAPP;
}
/* direct parent takes highest precedence */
@@ -440,27 +479,15 @@ static gboolean place_under_mouse(ObClient *client, gint *x, gint *y)
return TRUE;
}
-static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
+static gboolean place_per_app_setting(ObClient *client, Rect *screen,
+ gint *x, gint *y,
ObAppSettings *settings)
{
- Rect *screen = NULL;
-
if (!settings || (settings && !settings->pos_given))
return FALSE;
ob_debug("placing by per-app settings");
- /* Find which head the pointer is on */
- if (settings->monitor == 0)
- /* this can return NULL */
- screen = pick_pointer_head(client);
- else {
- guint m = settings->monitor;
- if (m < 1 || m > screen_num_monitors)
- m = screen_monitor_primary(TRUE) + 1;
- screen = screen_area(client->desktop, m - 1, NULL);
- }
-
if (settings->position.x.center)
*x = screen->x + screen->width / 2 - client->area.width / 2;
else if (settings->position.x.opposite)
@@ -481,7 +508,6 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
if (settings->position.y.denom)
*y = (*y * screen->height) / settings->position.y.denom;
- g_slice_free(Rect, screen);
return TRUE;
}
@@ -548,10 +574,10 @@ gboolean place_client(ObClient *client, gboolean foreground, gint *x, gint *y,
!(settings && settings->pos_given)))
return FALSE;
- area = pick_head(client, foreground);
+ area = pick_head(client, foreground, settings);
/* try a number of methods */
- ret = place_per_app_setting(client, x, y, settings) ||
+ ret = place_per_app_setting(client, area, x, y, settings) ||
place_transient_splash(client, area, x, y) ||
(config_place_policy == OB_PLACE_POLICY_MOUSE &&
place_under_mouse(client, x, y)) ||
View
13 openbox/screen.c
@@ -249,6 +249,7 @@ gboolean screen_annex(void)
supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG);
supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_NORMAL);
supported[i++] = OBT_PROP_ATOM(NET_WM_ALLOWED_ACTIONS);
+ supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_OPACITY);
supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MOVE);
supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_RESIZE);
supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MINIMIZE);
@@ -479,7 +480,6 @@ void screen_shutdown(gboolean reconfig)
void screen_resize(void)
{
- static gint oldw = 0, oldh = 0;
gint w, h;
GList *it;
gulong geometry[2];
@@ -487,10 +487,6 @@ void screen_resize(void)
w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));
- if (w == oldw && h == oldh) return;
-
- oldw = w; oldh = h;
-
/* Set the _NET_DESKTOP_GEOMETRY hint */
screen_physical_size.width = geometry[0] = w;
screen_physical_size.height = geometry[1] = h;
@@ -503,9 +499,10 @@ void screen_resize(void)
/* this calls screen_update_areas(), which we need ! */
dock_configure();
- if (oldw)
- for (it = client_list; it; it = g_list_next(it))
- client_move_onscreen(it->data, FALSE);
+ for (it = client_list; it; it = g_list_next(it)) {
+ client_move_onscreen(it->data, FALSE);
+ client_reconfigure(it->data, FALSE);
+ }
}
void screen_set_num_desktops(guint num)
Please sign in to comment.
Something went wrong with that request. Please try again.