summaryrefslogtreecommitdiffstats
path: root/compton.c
diff options
context:
space:
mode:
authorRichard Grenville <pyxlcy@gmail.com>2013-01-19 20:20:27 +0800
committerRichard Grenville <pyxlcy@gmail.com>2013-01-19 20:20:27 +0800
commit32132312985e3a7f63444dcd4b54f821520a6042 (patch)
treee00f787bf4b13ca6b4e92eec1bea392ad2296499 /compton.c
parenta5dc829944175cab684e5b4488ddff409f308099 (diff)
downloadtdebase-32132312985e3a7f63444dcd4b54f821520a6042.tar.gz
tdebase-32132312985e3a7f63444dcd4b54f821520a6042.zip
Feature #80: D-Bus support
- Add D-Bus support. Currently 7 methods are available: "reset" (same as SIGUSR1), "list_win" (list the windows compton manages), "win_get" (get a property of the window), "win_set" (set a property of the window), "find_win" (find window based on client window / focus), "opts_get" (get the value of a compton option), and "opts_set" (set the value of a compton option), together with 4 signals: "win_added", "win_destroyed", "win_mapped", "win_unmapped". - D-Bus support depends on libdbus. - As there are many items and my time is tight, no much tests are done. Bugs to be expected. - Create a new header file `common.h` that contains shared content. - Fix some bugs in timeout handling. - Update file headers in all source files. - Re-enable --unredir-if-possible on multi-screen set-ups, as the user could turn if off manually anyway. - Check if the window is mapped in `repair_win()`. - Add ps->track_atom_lst and its handlers, to prepare for the new condition format. - Known issue 1: "win_get", "win_set", "opts_get", "opts_set" support a very limited number of targets only. New ones will be added gradually. - Known issue 2: Accidental drop of D-Bus connection is not handled. - Known issue 3: Introspection does not reveal all available methods, because some methods have unpredictable prototypes. Still hesitating about what to do... - Known issue 4: Error handling is not finished yet. Compton does not always reply with the correct error message (but it does print out the correct error message, usually).
Diffstat (limited to 'compton.c')
-rw-r--r--compton.c155
1 files changed, 141 insertions, 14 deletions
diff --git a/compton.c b/compton.c
index f933d437d..90133d11c 100644
--- a/compton.c
+++ b/compton.c
@@ -3,7 +3,7 @@
*
* Based on `xcompmgr` - Copyright (c) 2003, Keith Packard
*
- * Copyright (c) 2011, Christopher Jeffrey
+ * Copyright (c) 2011-2013, Christopher Jeffrey
* See LICENSE for more information.
*
*/
@@ -837,7 +837,7 @@ determine_evmask(session_t *ps, Window wid, win_evmode_t mode) {
// Check if it's a mapped client window
if (WIN_EVMODE_CLIENT == mode
|| ((w = find_toplevel(ps, wid)) && IsViewable == w->a.map_state)) {
- if (ps->o.frame_opacity || ps->o.track_wdata
+ if (ps->o.frame_opacity || ps->o.track_wdata || ps->track_atom_lst
|| ps->o.detect_client_opacity)
evmask |= PropertyChangeMask;
}
@@ -1361,8 +1361,7 @@ paint_preprocess(session_t *ps, win *list) {
// Disable unredirection for multi-screen setups
if (WMODE_SOLID == w->mode
&& (!w->frame_opacity || !win_has_frame(w))
- && win_is_fullscreen(ps, w)
- && ScreenCount(ps->dpy) <= 1)
+ && win_is_fullscreen(ps, w))
ps->unredir_possible = true;
}
@@ -1848,6 +1847,9 @@ add_damage(session_t *ps, XserverRegion damage) {
static void
repair_win(session_t *ps, win *w) {
+ if (IsViewable != w->a.map_state)
+ return;
+
XserverRegion parts;
if (!w->damaged) {
@@ -1986,6 +1988,13 @@ map_win(session_t *ps, Window id) {
if (w->need_configure) {
configure_win(ps, &w->queue_configure);
}
+
+#ifdef CONFIG_DBUS
+ // Send D-Bus signal
+ if (ps->o.dbus) {
+ cdbus_ev_win_mapped(ps, w);
+ }
+#endif
}
static void
@@ -2042,6 +2051,13 @@ unmap_win(session_t *ps, Window id) {
// don't care about properties anymore
win_ev_stop(ps, w);
+
+#ifdef CONFIG_DBUS
+ // Send D-Bus signal
+ if (ps->o.dbus) {
+ cdbus_ev_win_unmapped(ps, w);
+ }
+#endif
}
static opacity_t
@@ -2583,8 +2599,8 @@ add_win(session_t *ps, Window id, Window prev) {
// Fill structure
new->id = id;
- set_ignore_next(ps);
+ set_ignore_next(ps);
if (!XGetWindowAttributes(ps->dpy, id, &new->a)) {
// Failed to get window attributes. Which probably means, the window
// is gone already.
@@ -2608,7 +2624,14 @@ add_win(session_t *ps, Window id, Window prev) {
new->next = *p;
*p = new;
- if (map_state == IsViewable) {
+#ifdef CONFIG_DBUS
+ // Send D-Bus signal
+ if (ps->o.dbus) {
+ cdbus_ev_win_added(ps, new);
+ }
+#endif
+
+ if (IsViewable == map_state) {
map_win(ps, id);
}
@@ -2811,6 +2834,13 @@ destroy_win(session_t *ps, Window id) {
// Fading out the window
w->flags |= WFLAG_OPCT_CHANGE;
set_fade_callback(ps, w, destroy_callback, false);
+
+#ifdef CONFIG_DBUS
+ // Send D-Bus signal
+ if (ps->o.dbus) {
+ cdbus_ev_win_destroyed(ps, w);
+ }
+#endif
}
}
@@ -3252,6 +3282,58 @@ win_get_class(session_t *ps, win *w) {
return true;
}
+#ifdef CONFIG_DBUS
+/** @name DBus hooks
+ */
+///@{
+
+/**
+ * Set w->shadow_force of a window.
+ */
+void
+win_set_shadow_force(session_t *ps, win *w, switch_t val) {
+ if (val != w->shadow_force) {
+ w->shadow_force = val;
+ win_determine_shadow(ps, w);
+ }
+}
+
+/**
+ * Set w->focused_force of a window.
+ */
+void
+win_set_focused_force(session_t *ps, win *w, switch_t val) {
+ if (val != w->focused_force) {
+ w->focused_force = val;
+ win_update_focused(ps, w);
+ }
+}
+
+/**
+ * Set w->invert_color_force of a window.
+ */
+void
+win_set_invert_color_force(session_t *ps, win *w, switch_t val) {
+ if (val != w->invert_color_force) {
+ w->invert_color_force = 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
+
#ifdef DEBUG_EVENTS
static int
ev_serial(XEvent *ev) {
@@ -3647,6 +3729,17 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
}
}
+ // Check for other atoms we are tracking
+ for (latom_t *platom = ps->track_atom_lst; platom; platom = platom->next) {
+ if (platom->atom == ev->atom) {
+ win *w = find_win(ps, ev->window);
+ if (!w)
+ w = find_toplevel(ps, ev->window);
+ if (w)
+ win_on_wdata_change(ps, w);
+ break;
+ }
+ }
}
inline static void
@@ -5129,8 +5222,7 @@ timeout_get_poll_time(session_t *ps) {
// Traverse throught the timeout linked list
for (timeout_t *ptmout = ps->tmout_lst; ptmout; ptmout = ptmout->next) {
if (ptmout->enabled) {
- // Truncate the last run time to the closest interval
- time_ms_t newrun = ptmout->firstrun + ((ptmout->lastrun - ptmout->firstrun) / ptmout->interval + 1) * ptmout->interval;
+ time_ms_t newrun = timeout_get_newrun(ptmout);
if (newrun <= now) {
wait = 0;
break;
@@ -5149,7 +5241,7 @@ timeout_get_poll_time(session_t *ps) {
/**
* Insert a new timeout.
*/
-static timeout_t *
+timeout_t *
timeout_insert(session_t *ps, time_ms_t interval,
bool (*callback)(session_t *ps, timeout_t *ptmout), void *data) {
const static timeout_t tmout_def = {
@@ -5184,7 +5276,7 @@ timeout_insert(session_t *ps, time_ms_t interval,
* @return true if we have found the timeout and removed it, false
* otherwise
*/
-static bool
+bool
timeout_drop(session_t *ps, timeout_t *prm) {
timeout_t **pplast = &ps->tmout_lst;
@@ -5224,12 +5316,14 @@ static bool
timeout_run(session_t *ps) {
const time_ms_t now = get_time_ms();
bool ret = false;
+ timeout_t *pnext = NULL;
- for (timeout_t *ptmout = ps->tmout_lst; ptmout; ptmout = ptmout->next) {
+ for (timeout_t *ptmout = ps->tmout_lst; ptmout; ptmout = pnext) {
+ pnext = ptmout->next;
if (ptmout->enabled) {
const time_ms_t max = now +
(time_ms_t) (ptmout->interval * TIMEOUT_RUN_TOLERANCE);
- time_ms_t newrun = ptmout->firstrun + ((ptmout->lastrun - ptmout->firstrun) / ptmout->interval + 1) * ptmout->interval;
+ time_ms_t newrun = timeout_get_newrun(ptmout);
if (newrun <= max) {
ret = true;
timeout_invoke(ps, ptmout);
@@ -5243,7 +5337,7 @@ timeout_run(session_t *ps) {
/**
* Invoke a timeout.
*/
-static void
+void
timeout_invoke(session_t *ps, timeout_t *ptmout) {
const time_ms_t now = get_time_ms();
ptmout->lastrun = now;
@@ -5301,6 +5395,12 @@ mainloop(session_t *ps) {
return true;
}
+#ifdef CONFIG_DBUS
+ if (ps->o.dbus) {
+ cdbus_loop(ps);
+ }
+#endif
+
if (ps->reset)
return false;
@@ -5531,7 +5631,13 @@ session_init(session_t *ps_old, int argc, char **argv) {
.atom_ewmh_active_win = None,
.atom_compton_shadow = None,
.atom_win_type = None,
- .atoms_wintypes = { 0 }
+ .atoms_wintypes = { 0 },
+ .track_atom_lst = NULL,
+
+#ifdef CONFIG_DBUS
+ .dbus_conn = NULL,
+ .dbus_service = NULL,
+#endif
};
// Allocate a session and copy default values into it
@@ -5740,6 +5846,19 @@ session_init(session_t *ps_old, int argc, char **argv) {
XUngrabServer(ps->dpy);
+ // Initialize DBus
+ if (ps->o.dbus) {
+#ifdef CONFIG_DBUS
+ cdbus_init(ps);
+ if (!ps->dbus_conn) {
+ cdbus_destroy(ps);
+ ps->o.dbus = false;
+ }
+#else
+ printf_errfq(1, "(): DBus support not compiled in!");
+#endif
+ }
+
// Fork to background, if asked
if (ps->o.fork_after_register) {
if (!fork_after(ps)) {
@@ -5770,6 +5889,14 @@ session_destroy(session_t *ps) {
// Stop listening to events on root window
XSelectInput(ps->dpy, ps->root, 0);
+#ifdef CONFIG_DBUS
+ // Kill DBus connection
+ if (ps->o.dbus)
+ cdbus_destroy(ps);
+
+ free(ps->dbus_service);
+#endif
+
// Free window linked list
{
win *next = NULL;