summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Grenville <[email protected]>2013-01-24 13:38:03 +0800
committerRichard Grenville <[email protected]>2013-01-24 13:38:03 +0800
commit56a35506b1f65bd36e4f5b30054b348eea79f515 (patch)
tree731eb86149964e096cccce4b331316e8fb4fffa1
parent32132312985e3a7f63444dcd4b54f821520a6042 (diff)
downloadtdebase-56a35506b1f65bd36e4f5b30054b348eea79f515.tar.gz
tdebase-56a35506b1f65bd36e4f5b30054b348eea79f515.zip
Bug fix #84: Root window not repainted sometimes on wallpaper change
- Fix a bug that root window is not repainted on wallpaper change unless an Expose X event is received. Seemingly, if there's no mapped window on a screen, X will not send an Expose event when the wallpaper changes. Thanks to baskerville for reporting. - Fix a X Pixmap leak when there's no existing wallpaper pixmap found. - Fix a bug in mstrncpy() that null character is not added to the end of the copied string. - Make VSYNC_STRS public, for use in src/dbus.c. Adjust the type of WINTYPES array. Add NUM_VSYNC. - Add more targets for various D-Bus methods. Add "bad_target" D-Bus error. Improve error handling. Add more helper functions to append arguments to a D-Bus message. Add Introspect method to D-Bus introspection reply. - Add public declarations of things in the new condition format code to common.h. Move definitions of some inline functions from compton.h to common.h. Make some functions public. Move wid_get_prop_adv() to compton.c. The primary code files of the new format src/c2.{c,h} will be published when ready. - Add support for dumping version string in Makefile (make version), to make snapshot generation easier. - Add repeated inclusion protection to common.h. - Update documentation. - Use gsed instead of sed in dbus-examples/cdbus-driver.sh if possible, as some BSD systems does not come with GNU sed by default. Thanks to DaChiChang for reporting. - Code clean-up. Small type changes in register_cm() to silence warnings. Quit on failure in parse_vsync(). Apply stricter checks in force_repaint().
-rw-r--r--common.h144
-rw-r--r--compton.c123
-rw-r--r--compton.h128
-rw-r--r--dbus.c140
-rw-r--r--dbus.h35
5 files changed, 383 insertions, 187 deletions
diff --git a/common.h b/common.h
index 31c9c2002..004d9553b 100644
--- a/common.h
+++ b/common.h
@@ -8,6 +8,9 @@
*
*/
+#ifndef COMPTON_COMMON_H
+#define COMPTON_COMMON_H
+
// === Options ===
// Debug options, enable them using -D in CFLAGS
@@ -22,6 +25,7 @@
// #define DEBUG_ALLOC_REG 1
// #define DEBUG_FRAME 1
// #define DEBUG_LEADER 1
+// #define DEBUG_C2 1
// #define MONITOR_REPAINT 1
// Whether to enable PCRE regular expression support in blacklists, enabled
@@ -40,6 +44,12 @@
// #define CONFIG_VSYNC_OPENGL 1
// Whether to enable DBus support with libdbus.
// #define CONFIG_DBUS 1
+// Whether to enable condition support.
+// #define CONFIG_C2 1
+
+#if !defined(CONFIG_C2) && defined(DEBUG_C2)
+#error Cannot enable c2 debugging without c2 support.
+#endif
// === Includes ===
@@ -264,6 +274,7 @@ typedef enum {
VSYNC_NONE,
VSYNC_DRM,
VSYNC_OPENGL,
+ NUM_VSYNC,
} vsync_t;
#ifdef CONFIG_VSYNC_OPENGL
@@ -286,9 +297,15 @@ struct _timeout_t;
struct _win;
+#ifdef CONFIG_C2
+typedef struct _c2_lptr c2_lptr_t;
+#endif
+
/// Structure representing all options.
typedef struct {
// === General ===
+ /// The display name we used. NULL means we are using the value of the
+ /// <code>DISPLAY</code> environment variable.
char *display;
/// Whether to try to detect WM windows and mark them as focused.
bool mark_wmwin_focused;
@@ -534,13 +551,13 @@ typedef struct {
/// Nanosecond offset of the first painting.
long paint_tm_offset;
- #ifdef CONFIG_VSYNC_DRM
+#ifdef CONFIG_VSYNC_DRM
// === DRM VSync related ===
/// File descriptor of DRI device file. Used for DRM VSync.
int drm_fd;
- #endif
+#endif
- #ifdef CONFIG_VSYNC_OPENGL
+#ifdef CONFIG_VSYNC_OPENGL
// === OpenGL VSync related ===
/// GLX context.
GLXContext glx_context;
@@ -548,7 +565,7 @@ typedef struct {
f_GetVideoSync glx_get_video_sync;
/// Pointer to glXWaitVideoSyncSGI function.
f_WaitVideoSync glx_wait_video_sync;
- #endif
+#endif
// === X extension related ===
/// Event base number for X Fixes extension.
@@ -584,14 +601,14 @@ typedef struct {
int randr_event;
/// Error base number for X RandR extension.
int randr_error;
- #ifdef CONFIG_VSYNC_OPENGL
+#ifdef CONFIG_VSYNC_OPENGL
/// Whether X GLX extension exists.
bool glx_exists;
/// Event base number for X GLX extension.
int glx_event;
/// Error base number for X GLX extension.
int glx_error;
- #endif
+#endif
/// Whether X DBE extension exists.
bool dbe_exists;
/// Whether X Render convolution filter exists.
@@ -816,7 +833,8 @@ typedef enum {
WIN_EVMODE_CLIENT
} win_evmode_t;
-extern const char *WINTYPES[NUM_WINTYPES];
+extern const char * const WINTYPES[NUM_WINTYPES];
+extern const char * const VSYNC_STRS[NUM_VSYNC];
extern session_t *ps_g;
// == Debugging code ==
@@ -1055,6 +1073,7 @@ mstrncpy(const char *src, unsigned len) {
char *str = malloc(sizeof(char) * (len + 1));
strncpy(str, src, len);
+ str[len] = '\0';
return str;
}
@@ -1260,6 +1279,14 @@ fds_poll(session_t *ps, struct timeval *ptv) {
#undef CPY_FDS
/**
+ * Wrapper of XInternAtom() for convenience.
+ */
+static inline Atom
+get_atom(session_t *ps, const char *atom_name) {
+ return XInternAtom(ps->dpy, atom_name, False);
+}
+
+/**
* Find a window from window id in window linked list of the session.
*/
static inline win *
@@ -1326,6 +1353,86 @@ copy_region(const session_t *ps, XserverRegion oldregion) {
return region;
}
+/**
+ * Determine if a window has a specific property.
+ *
+ * @param ps current session
+ * @param w window to check
+ * @param atom atom of property to check
+ * @return 1 if it has the attribute, 0 otherwise
+ */
+static inline bool
+wid_has_prop(const session_t *ps, Window w, Atom atom) {
+ Atom type = None;
+ int format;
+ unsigned long nitems, after;
+ unsigned char *data;
+
+ if (Success == XGetWindowProperty(ps->dpy, w, atom, 0, 0, False,
+ AnyPropertyType, &type, &format, &nitems, &after, &data)) {
+ XFree(data);
+ if (type) return true;
+ }
+
+ return false;
+}
+
+winprop_t
+wid_get_prop_adv(const session_t *ps, Window w, Atom atom, long offset,
+ long length, Atom rtype, int rformat);
+
+/**
+ * Wrapper of wid_get_prop_adv().
+ */
+static inline winprop_t
+wid_get_prop(const session_t *ps, Window wid, Atom atom, long length,
+ Atom rtype, int rformat) {
+ return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat);
+}
+
+/**
+ * Get the numeric property value from a win_prop_t.
+ */
+static inline long
+winprop_get_int(winprop_t prop) {
+ long tgt = 0;
+
+ if (!prop.nitems)
+ return 0;
+
+ switch (prop.format) {
+ case 8: tgt = *(prop.data.p8); break;
+ case 16: tgt = *(prop.data.p16); break;
+ case 32: tgt = *(prop.data.p32); break;
+ default: assert(0);
+ break;
+ }
+
+ return tgt;
+}
+
+bool
+wid_get_text_prop(session_t *ps, Window wid, Atom prop,
+ char ***pstrlst, int *pnstr);
+
+/**
+ * Free a <code>winprop_t</code>.
+ *
+ * @param pprop pointer to the <code>winprop_t</code> to free.
+ */
+static inline void
+free_winprop(winprop_t *pprop) {
+ // Empty the whole structure to avoid possible issues
+ if (pprop->data.p8) {
+ XFree(pprop->data.p8);
+ pprop->data.p8 = NULL;
+ }
+ pprop->nitems = 0;
+}
+
+void
+force_repaint(session_t *ps);
+
#ifdef CONFIG_DBUS
/** @name DBus handling
*/
@@ -1363,8 +1470,25 @@ win_set_focused_force(session_t *ps, win *w, switch_t val);
void
win_set_invert_color_force(session_t *ps, win *w, switch_t val);
-
-void
-force_repaint(session_t *ps);
//!@}
#endif
+
+#ifdef CONFIG_C2
+/** @name c2
+ */
+///@{
+
+c2_lptr_t *
+c2_parse(session_t *ps, c2_lptr_t **pcondlst, char *pattern);
+
+c2_lptr_t *
+c2_free_lptr(c2_lptr_t *lp);
+
+bool
+c2_match(session_t *ps, win *w, const c2_lptr_t *condlst,
+ const c2_lptr_t **cache);
+#endif
+
+///@}
+
+#endif
diff --git a/compton.c b/compton.c
index 90133d11c..814bf4a3b 100644
--- a/compton.c
+++ b/compton.c
@@ -13,7 +13,7 @@
// === Global constants ===
/// Name strings for window types.
-const char *WINTYPES[NUM_WINTYPES] = {
+const char * const WINTYPES[NUM_WINTYPES] = {
"unknown",
"desktop",
"dock",
@@ -31,9 +31,16 @@ const char *WINTYPES[NUM_WINTYPES] = {
"dnd",
};
+/// Names of VSync modes
+const char * const VSYNC_STRS[NUM_VSYNC] = {
+ "none", // VSYNC_NONE
+ "drm", // VSYNC_DRM
+ "opengl", // VSYNC_OPENGL
+};
+
/// Names of root window properties that could point to a pixmap of
/// background.
-const char *background_props_str[] = {
+const static char *background_props_str[] = {
"_XROOTPMAP_ID",
"_XSETROOT_ID",
0,
@@ -535,6 +542,52 @@ should_ignore(session_t *ps, unsigned long sequence) {
// === Windows ===
/**
+ * Get a specific attribute of a window.
+ *
+ * Returns a blank structure if the returned type and format does not
+ * match the requested type and format.
+ *
+ * @param ps current session
+ * @param w window
+ * @param atom atom of attribute to fetch
+ * @param length length to read
+ * @param rtype atom of the requested type
+ * @param rformat requested format
+ * @return a <code>winprop_t</code> structure containing the attribute
+ * and number of items. A blank one on failure.
+ */
+winprop_t
+wid_get_prop_adv(const session_t *ps, Window w, Atom atom, long offset,
+ long length, Atom rtype, int rformat) {
+ Atom type = None;
+ int format = 0;
+ unsigned long nitems = 0, after = 0;
+ unsigned char *data = NULL;
+
+ if (Success == XGetWindowProperty(ps->dpy, w, atom, offset, length,
+ False, rtype, &type, &format, &nitems, &after, &data)
+ && nitems && (AnyPropertyType == type || type == rtype)
+ && (!format || format == rformat)
+ && (8 == format || 16 == format || 32 == format)) {
+ return (winprop_t) {
+ .data.p8 = data,
+ .nitems = nitems,
+ .type = type,
+ .format = format,
+ };
+ }
+
+ XFree(data);
+
+ return (winprop_t) {
+ .data.p8 = NULL,
+ .nitems = 0,
+ .type = AnyPropertyType,
+ .format = 0
+ };
+}
+
+/**
* Check if a window has rounded corners.
*/
static void
@@ -966,6 +1019,8 @@ root_tile_f(session_t *ps) {
c.alpha = 0xffff;
XRenderFillRectangle(
ps->dpy, PictOpSrc, picture, &c, 0, 0, 1, 1);
+
+ free_pixmap(ps, &pixmap);
}
return picture;
@@ -2120,10 +2175,8 @@ win_determine_mode(session_t *ps, win *w) {
* > window type default opacity (if not opaque)
* > inactive_opacity
*
- * @param dpy X display to use
+ * @param ps current session
* @param w struct _win object representing the window
- * @param refetch_prop whether _NET_WM_OPACITY of the window needs to be
- * refetched
*/
static void
calc_opacity(session_t *ps, win *w) {
@@ -2858,9 +2911,9 @@ root_damaged(session_t *ps) {
add_damage(ps, parts);
} */
}
- // Mark screen damaged if we are painting on overlay
- if (ps->o.paint_on_overlay)
- add_damage(ps, get_screen_region(ps));
+
+ // Mark screen damaged
+ force_repaint(ps);
}
static void
@@ -3133,7 +3186,7 @@ win_get_leader_raw(session_t *ps, win *w, int recursions) {
/**
* Get the value of a text property of a window.
*/
-static bool
+bool
wid_get_text_prop(session_t *ps, Window wid, Atom prop,
char ***pstrlst, int *pnstr) {
XTextProperty text_prop = { NULL, None, 0, 0 };
@@ -3282,6 +3335,19 @@ win_get_class(session_t *ps, win *w) {
return true;
}
+/**
+ * Force a full-screen repaint.
+ */
+void
+force_repaint(session_t *ps) {
+ assert(ps->screen_reg);
+ XserverRegion reg = None;
+ if (ps->screen_reg && (reg = copy_region(ps, ps->screen_reg))) {
+ ps->ev_received = true;
+ add_damage(ps, reg);
+ }
+}
+
#ifdef CONFIG_DBUS
/** @name DBus hooks
*/
@@ -3319,18 +3385,6 @@ win_set_invert_color_force(session_t *ps, win *w, switch_t val) {
win_determine_invert_color(ps, w);
}
}
-
-/**
- * Force a full-screen repaint.
- */
-void
-force_repaint(session_t *ps) {
- XserverRegion reg = None;
- if (ps->screen_reg && (reg = copy_region(ps, ps->screen_reg))) {
- ps->ev_received = true;
- add_damage(ps, reg);
- }
-}
//!@}
#endif
@@ -4039,6 +4093,9 @@ usage(void) {
"--invert-color-include condition\n"
" Specify a list of conditions of windows that should be painted with\n"
" inverted color. Resource-hogging, and is not well tested.\n"
+ "--dbus\n"
+ " Enable remote control via D-Bus. See the D-BUS API section in the\n"
+ " man page for more details.\n"
"\n"
"Format of a condition:\n"
"\n"
@@ -4068,7 +4125,6 @@ static void
register_cm(session_t *ps, bool want_glxct) {
Atom a;
char *buf;
- int len, s;
#ifdef CONFIG_VSYNC_OPENGL
// Create a window with the wanted GLX visual
@@ -4128,8 +4184,8 @@ register_cm(session_t *ps, bool want_glxct) {
Xutf8SetWMProperties(ps->dpy, ps->reg_win, "xcompmgr", "xcompmgr",
NULL, 0, NULL, NULL, NULL);
- len = strlen(REGISTER_PROP) + 2;
- s = ps->scr;
+ unsigned len = strlen(REGISTER_PROP) + 2;
+ int s = ps->scr;
while (s >= 10) {
++len;
@@ -4284,21 +4340,15 @@ open_config_file(char *cpath, char **ppath) {
*/
static inline void
parse_vsync(session_t *ps, const char *optarg) {
- const static char * const vsync_str[] = {
- "none", // VSYNC_NONE
- "drm", // VSYNC_DRM
- "opengl", // VSYNC_OPENGL
- };
-
vsync_t i;
- for (i = 0; i < (sizeof(vsync_str) / sizeof(vsync_str[0])); ++i)
- if (!strcasecmp(optarg, vsync_str[i])) {
+ for (i = 0; i < (sizeof(VSYNC_STRS) / sizeof(VSYNC_STRS[0])); ++i)
+ if (!strcasecmp(optarg, VSYNC_STRS[i])) {
ps->o.vsync = i;
break;
}
- if ((sizeof(vsync_str) / sizeof(vsync_str[0])) == i) {
- fputs("Invalid --vsync argument. Ignored.\n", stderr);
+ if ((sizeof(VSYNC_STRS) / sizeof(VSYNC_STRS[0])) == i) {
+ printf_errfq(1, "(\"%s\"): Invalid --vsync argument.", optarg);
}
}
@@ -6114,6 +6164,11 @@ main(int argc, char **argv) {
printf_errf("Failed to create new session.");
return 1;
}
+#ifdef DEBUG_C2
+ // c2_parse(ps_g, NULL, "name ~= \"master\"");
+ // c2_parse(ps_g, NULL, "n:e:Notification");
+ c2_parse(ps_g, NULL, "(WM_NAME:16s = 'Notification' || class_g = 'fox') && class_g = 'fox'");
+#endif
session_run(ps_g);
ps_old = ps_g;
session_destroy(ps_g);
diff --git a/compton.h b/compton.h
index c30991076..7670424e9 100644
--- a/compton.h
+++ b/compton.h
@@ -53,14 +53,6 @@ static int
should_ignore(session_t *ps, unsigned long sequence);
/**
- * Wrapper of XInternAtom() for convenience.
- */
-static inline Atom
-get_atom(session_t *ps, const char *atom_name) {
- return XInternAtom(ps->dpy, atom_name, False);
-}
-
-/**
* Return the painting target window.
*/
static inline Window
@@ -292,122 +284,6 @@ solid_picture(session_t *ps, bool argb, double a,
double r, double g, double b);
/**
- * Determine if a window has a specific property.
- *
- * @param session_t current session
- * @param w window to check
- * @param atom atom of property to check
- * @return 1 if it has the attribute, 0 otherwise
- */
-static inline bool
-wid_has_prop(const session_t *ps, Window w, Atom atom) {
- Atom type = None;
- int format;
- unsigned long nitems, after;
- unsigned char *data;
-
- if (Success == XGetWindowProperty(ps->dpy, w, atom, 0, 0, False,
- AnyPropertyType, &type, &format, &nitems, &after, &data)) {
- XFree(data);
- if (type) return true;
- }
-
- return false;
-}
-
-/**
- * Get a specific attribute of a window.
- *
- * Returns a blank structure if the returned type and format does not
- * match the requested type and format.
- *
- * @param session_t current session
- * @param w window
- * @param atom atom of attribute to fetch
- * @param length length to read
- * @param rtype atom of the requested type
- * @param rformat requested format
- * @return a <code>winprop_t</code> structure containing the attribute
- * and number of items. A blank one on failure.
- */
-// TODO: Move to compton.c
-static winprop_t
-wid_get_prop_adv(const session_t *ps, Window w, Atom atom, long offset,
- long length, Atom rtype, int rformat) {
- Atom type = None;
- int format = 0;
- unsigned long nitems = 0, after = 0;
- unsigned char *data = NULL;
-
- if (Success == XGetWindowProperty(ps->dpy, w, atom, offset, length,
- False, rtype, &type, &format, &nitems, &after, &data)
- && nitems && (AnyPropertyType == type || type == rtype)
- && (!format || format == rformat)
- && (8 == format || 16 == format || 32 == format)) {
- return (winprop_t) {
- .data.p8 = data,
- .nitems = nitems,
- .type = type,
- .format = format,
- };
- }
-
- XFree(data);
-
- return (winprop_t) {
- .data.p8 = NULL,
- .nitems = 0,
- .type = AnyPropertyType,
- .format = 0
- };
-}
-
-/**
- * Wrapper of wid_get_prop_adv().
- */
-static inline winprop_t
-wid_get_prop(const session_t *ps, Window wid, Atom atom, long length,
- Atom rtype, int rformat) {
- return wid_get_prop_adv(ps, wid, atom, 0L, length, rtype, rformat);
-}
-
-/**
- * Get the numeric property value from a win_prop_t.
- */
-static inline long
-winprop_get_int(winprop_t prop) {
- long tgt = 0;
-
- if (!prop.nitems)
- return 0;
-
- switch (prop.format) {
- case 8: tgt = *(prop.data.p8); break;
- case 16: tgt = *(prop.data.p16); break;
- case 32: tgt = *(prop.data.p32); break;
- default: assert(0);
- break;
- }
-
- return tgt;
-}
-
-/**
- * Free a <code>winprop_t</code>.
- *
- * @param pprop pointer to the <code>winprop_t</code> to free.
- */
-static inline void
-free_winprop(winprop_t *pprop) {
- // Empty the whole structure to avoid possible issues
- if (pprop->data.p8) {
- XFree(pprop->data.p8);
- pprop->data.p8 = NULL;
- }
- pprop->nitems = 0;
-}
-
-/**
* Stop listening for events on a particular window.
*/
static inline void
@@ -768,10 +644,6 @@ error(Display *dpy, XErrorEvent *ev);
static void
expose_root(session_t *ps, XRectangle *rects, int nrects);
-static bool
-wid_get_text_prop(session_t *ps, Window wid, Atom prop,
- char ***pstrlst, int *pnstr);
-
static Window
wid_get_prop_window(session_t *ps, Window wid, Atom aprop);
diff --git a/dbus.c b/dbus.c
index 16be7cc8f..a86ed174d 100644
--- a/dbus.c
+++ b/dbus.c
@@ -267,6 +267,48 @@ cdbus_apdarg_bool(session_t *ps, DBusMessage *msg, const void *data) {
}
/**
+ * Callback to append an int32 argument to a message.
+ */
+static bool
+cdbus_apdarg_int32(session_t *ps, DBusMessage *msg, const void *data) {
+ if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, data,
+ DBUS_TYPE_INVALID)) {
+ printf_errf("(): Failed to append argument.");
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Callback to append an uint32 argument to a message.
+ */
+static bool
+cdbus_apdarg_uint32(session_t *ps, DBusMessage *msg, const void *data) {
+ if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, data,
+ DBUS_TYPE_INVALID)) {
+ printf_errf("(): Failed to append argument.");
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Callback to append a double argument to a message.
+ */
+static bool
+cdbus_apdarg_double(session_t *ps, DBusMessage *msg, const void *data) {
+ if (!dbus_message_append_args(msg, DBUS_TYPE_DOUBLE, data,
+ DBUS_TYPE_INVALID)) {
+ printf_errf("(): Failed to append argument.");
+ return false;
+ }
+
+ return true;
+}
+
+/**
* Callback to append a Window argument to a message.
*/
static bool
@@ -639,6 +681,21 @@ cdbus_process_win_get(session_t *ps, DBusMessage *msg) {
return true; \
}
+ cdbus_m_win_get_do(id, cdbus_reply_wid);
+
+ // next
+ if (!strcmp("next", target)) {
+ cdbus_reply_wid(ps, msg, (w->next ? w->next->id: 0));
+ return true;
+ }
+
+ // map_state
+ if (!strcmp("map_state", target)) {
+ cdbus_reply_bool(ps, msg, w->a.map_state);
+ return true;
+ }
+
+ cdbus_m_win_get_do(mode, cdbus_reply_enum);
cdbus_m_win_get_do(client_win, cdbus_reply_wid);
cdbus_m_win_get_do(damaged, cdbus_reply_bool);
cdbus_m_win_get_do(destroyed, cdbus_reply_bool);
@@ -649,15 +706,22 @@ cdbus_process_win_get(session_t *ps, DBusMessage *msg) {
cdbus_m_win_get_do(shadow_force, cdbus_reply_enum);
cdbus_m_win_get_do(focused_force, cdbus_reply_enum);
cdbus_m_win_get_do(invert_color_force, cdbus_reply_enum);
- if (!strcmp("map_state", target)) {
- cdbus_reply_bool(ps, msg, w->a.map_state);
- return true;
- }
+ cdbus_m_win_get_do(name, cdbus_reply_string);
+ cdbus_m_win_get_do(class_instance, cdbus_reply_string);
+ cdbus_m_win_get_do(class_general, cdbus_reply_string);
+ cdbus_m_win_get_do(role, cdbus_reply_string);
+ cdbus_m_win_get_do(opacity, cdbus_reply_uint32);
+ cdbus_m_win_get_do(frame_opacity, cdbus_reply_double);
+ cdbus_m_win_get_do(left_width, cdbus_reply_uint32);
+ cdbus_m_win_get_do(right_width, cdbus_reply_uint32);
+ cdbus_m_win_get_do(top_width, cdbus_reply_uint32);
+ cdbus_m_win_get_do(bottom_width, cdbus_reply_uint32);
#undef cdbus_m_win_get_do
- printf_errf("(): No matching target found.");
+ printf_errf("(): " CDBUS_ERROR_BADTGT_S, target);
+ cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
- return false;
+ return true;
}
/**
@@ -723,9 +787,10 @@ cdbus_process_win_set(session_t *ps, DBusMessage *msg) {
}
#undef cdbus_m_win_set_do
- printf_errf("(): No matching target found.");
+ printf_errf("(): " CDBUS_ERROR_BADTGT_S, target);
+ cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
- return false;
+ return true;
cdbus_process_win_set_success:
if (!dbus_message_get_no_reply(msg))
@@ -761,9 +826,10 @@ cdbus_process_find_win(session_t *ps, DBusMessage *msg) {
wid = w->id;
}
else {
- printf_errf("(): No matching target found.");
+ printf_errf("(): " CDBUS_ERROR_BADTGT_S, target);
+ cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
- return false;
+ return true;
}
cdbus_reply_wid(ps, msg, wid);
@@ -787,7 +853,12 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) {
return true; \
}
- cdbus_m_opts_get_do(display, cdbus_reply_string);
+ // display
+ if (!strcmp("display", target)) {
+ cdbus_reply_string(ps, msg, DisplayString(ps->dpy));
+ return true;
+ }
+
cdbus_m_opts_get_do(mark_wmwin_focused, cdbus_reply_bool);
cdbus_m_opts_get_do(mark_ovredir_focused, cdbus_reply_bool);
cdbus_m_opts_get_do(fork_after_register, cdbus_reply_bool);
@@ -797,12 +868,45 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg) {
cdbus_m_opts_get_do(logpath, cdbus_reply_string);
cdbus_m_opts_get_do(synchronize, cdbus_reply_bool);
+ cdbus_m_opts_get_do(refresh_rate, cdbus_reply_int32);
+ cdbus_m_opts_get_do(sw_opti, cdbus_reply_bool);
+ if (!strcmp("vsync", target)) {
+ assert(ps->o.vsync < sizeof(VSYNC_STRS) / sizeof(VSYNC_STRS[0]));
+ cdbus_reply_string(ps, msg, VSYNC_STRS[ps->o.vsync]);
+ return true;
+ }
+ cdbus_m_opts_get_do(dbe, cdbus_reply_bool);
+ cdbus_m_opts_get_do(vsync_aggressive, cdbus_reply_bool);
+
+ cdbus_m_opts_get_do(shadow_red, cdbus_reply_double);
+ cdbus_m_opts_get_do(shadow_green, cdbus_reply_double);
+ cdbus_m_opts_get_do(shadow_blue, cdbus_reply_double);
+ cdbus_m_opts_get_do(shadow_radius, cdbus_reply_int32);
+ cdbus_m_opts_get_do(shadow_offset_x, cdbus_reply_int32);
+ cdbus_m_opts_get_do(shadow_offset_y, cdbus_reply_int32);
+ cdbus_m_opts_get_do(shadow_opacity, cdbus_reply_double);
cdbus_m_opts_get_do(clear_shadow, cdbus_reply_bool);
+
+ cdbus_m_opts_get_do(blur_background, cdbus_reply_bool);
+ cdbus_m_opts_get_do(blur_background_frame, cdbus_reply_bool);
+ cdbus_m_opts_get_do(blur_background_fixed, cdbus_reply_bool);
+
+ cdbus_m_opts_get_do(inactive_dim, cdbus_reply_double);
+ cdbus_m_opts_get_do(inactive_dim_fixed, cdbus_reply_bool);
+
+ cdbus_m_opts_get_do(use_ewmh_active_win, cdbus_reply_bool);
+ cdbus_m_opts_get_do(detect_transient, cdbus_reply_bool);
+ cdbus_m_opts_get_do(detect_client_leader, cdbus_reply_bool);
+
+ cdbus_m_opts_get_do(track_focus, cdbus_reply_bool);
+ cdbus_m_opts_get_do(track_wdata, cdbus_reply_bool);
+ cdbus_m_opts_get_do(track_leader, cdbus_reply_bool);
#undef cdbus_m_opts_get_do
- printf_errf("(): No matching target found.");
+ printf_errf("(): " CDBUS_ERROR_BADTGT_S, target);
+ cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
- return false;
+ return true;
}
/**
@@ -849,9 +953,10 @@ cdbus_process_opts_set(session_t *ps, DBusMessage *msg) {
}
#undef cdbus_m_opts_set_do
- printf_errf("(): No matching target found.");
+ printf_errf("(): " CDBUS_ERROR_BADTGT_S, target);
+ cdbus_reply_err(ps, msg, CDBUS_ERROR_BADTGT, CDBUS_ERROR_BADTGT_S, target);
- return false;
+ return true;
cdbus_process_opts_set_success:
if (!dbus_message_get_no_reply(msg))
@@ -868,6 +973,11 @@ cdbus_process_introspect(session_t *ps, DBusMessage *msg) {
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
"<node name='" CDBUS_OBJECT_NAME "'>\n"
+ " <interface name='org.freedesktop.DBus.Introspectable'>\n"
+ " <method name='Introspect'>\n"
+ " <arg name='data' direction='out' type='s' />\n"
+ " </method>\n"
+ " </interface>\n"
" <interface name='" CDBUS_INTERFACE_NAME "'>\n"
" <signal name='win_added'>\n"
" <arg name='wid' type='" CDBUS_TYPE_WINDOW_STR "'/>\n"
diff --git a/dbus.h b/dbus.h
index fb51c8cc4..e69a6ae9b 100644
--- a/dbus.h
+++ b/dbus.h
@@ -24,6 +24,8 @@
#define CDBUS_ERROR_BADARG_S "Something wrong in arguments?"
#define CDBUS_ERROR_BADWIN CDBUS_ERROR_PREFIX ".bad_window"
#define CDBUS_ERROR_BADWIN_S "Requested window %#010lx not found."
+#define CDBUS_ERROR_BADTGT CDBUS_ERROR_PREFIX ".bad_target"
+#define CDBUS_ERROR_BADTGT_S "Target \"%s\" not found."
#define CDBUS_ERROR_FORBIDDEN CDBUS_ERROR_PREFIX ".forbidden"
#define CDBUS_ERROR_FORBIDDEN_S "Incorrect password, access denied."
@@ -76,6 +78,15 @@ static bool
cdbus_apdarg_bool(session_t *ps, DBusMessage *msg, const void *data);
static bool
+cdbus_apdarg_int32(session_t *ps, DBusMessage *msg, const void *data);
+
+static bool
+cdbus_apdarg_uint32(session_t *ps, DBusMessage *msg, const void *data);
+
+static bool
+cdbus_apdarg_double(session_t *ps, DBusMessage *msg, const void *data);
+
+static bool
cdbus_apdarg_wid(session_t *ps, DBusMessage *msg, const void *data);
static bool
@@ -146,6 +157,30 @@ cdbus_reply_bool(session_t *ps, DBusMessage *srcmsg, bool bval) {
}
/**
+ * Send a reply with an int32 argument.
+ */
+static inline bool
+cdbus_reply_int32(session_t *ps, DBusMessage *srcmsg, int32_t val) {
+ return cdbus_reply(ps, srcmsg, cdbus_apdarg_int32, &val);
+}
+
+/**
+ * Send a reply with an uint32 argument.
+ */
+static inline bool
+cdbus_reply_uint32(session_t *ps, DBusMessage *srcmsg, uint32_t val) {
+ return cdbus_reply(ps, srcmsg, cdbus_apdarg_uint32, &val);
+}
+
+/**
+ * Send a reply with a double argument.
+ */
+static inline bool
+cdbus_reply_double(session_t *ps, DBusMessage *srcmsg, double val) {
+ return cdbus_reply(ps, srcmsg, cdbus_apdarg_double, &val);
+}
+
+/**
* Send a reply with a wid argument.
*/
static inline bool