diff options
author | Richard Grenville <pyxlcy@gmail.com> | 2013-01-19 20:20:27 +0800 |
---|---|---|
committer | Richard Grenville <pyxlcy@gmail.com> | 2013-01-19 20:20:27 +0800 |
commit | 32132312985e3a7f63444dcd4b54f821520a6042 (patch) | |
tree | e00f787bf4b13ca6b4e92eec1bea392ad2296499 /compton.c | |
parent | a5dc829944175cab684e5b4488ddff409f308099 (diff) | |
download | tdebase-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.c | 155 |
1 files changed, 141 insertions, 14 deletions
@@ -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; |