chjj / compton

A compositor for X11.
Other
2.25k stars 500 forks source link

Compton's frame_opacity not working properly with ARGB windows. #240

Open ptrxyz opened 10 years ago

ptrxyz commented 10 years ago

I am using xmonad with compton (latest git) and termite (V9). Since V9 termite supports true ARGB transparency, Xmonad draws 24bit-RGB window frames. If I turn on compton, the window frames get semi-transparent, even if i start compton using

"compton --config /dev/null -e 1.0"

The only work around I see is to revert termite to V8 (no transparency support). However a fix would be appreciated.

actionless commented 10 years ago

when i using st with argb patch and awesome wm i don't facing any problems related to frame opacity

can u try different terminal and wm to be totally sure it's not termite or xmonad issue?

ptrxyz commented 10 years ago

I tested dwm in exchange for xmonad and urxvt in exchange for termite. Termite + dwm = same bug urxvt + dwm/xmonad = no bug

So the bug seems to be related to termite. Checking their gitlog shows that there was a change in how transparency gets handeled somewhere between V8 and V9. However I don't understand how termite/any program can effect the drawing of the window's managers borders. And why it works with compton turned off then.

But actually I am not too deep into "all that X-stuff", so could you maybe give me a rough explanation what could cause that wrong behaviour so I could point the termite developers on something?

actionless commented 10 years ago

what could cause that wrong behaviour

mb it's designed to set transparency for the full window instead of drawing argb, ie like transset is doing? i remember similar behavior in few other applications

and also does that behavior reproduces when using other compositors?

ptrxyz commented 10 years ago

Yup, same behavior with xcompmgr. I guess it might be related to termite. I will report the bug there and see if they can do something about it.

richardgv commented 10 years ago

I'm able to reproduce the problem with both terminte (with true transparency) and urxvt (with -depth 32 -bg rgba:4444/4444/4444/4444 for true transparency) under dwm. The problem I found here is very similar to #139: The WM fails to adapt to non-default visuals (32-bit ARGB visual in the case).

My patch to fix the issue in dwm-6.0:

(Update: Seemingly GitHub does not preserve tabs here very well. I posted the patch to gist: https://gist.github.com/richardgv/ee2fe54d9753d1e6a071 )

--- dwm.c   2011-12-19 23:02:46.000000000 +0800
+++ dwm.new.c   2014-11-08 12:44:10.689875202 +0800
@@ -187,6 +187,7 @@
 static void focusmon(const Arg *arg);
 static void focusstack(const Arg *arg);
 static unsigned long getcolor(const char *colstr);
+static unsigned long getcolor_in_window(const char *colstr, Window w, unsigned long fallback);
 static Bool getrootptr(int *x, int *y);
 static long getstate(Window w);
 static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
@@ -855,7 +856,7 @@
        detachstack(c);
        attachstack(c);
        grabbuttons(c, True);
-       XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
+       XSetWindowBorder(dpy, c->win, getcolor_in_window(selbordercolor, c->win, dc.norm[ColBorder]));
        setfocus(c);
    }
    else
@@ -936,6 +937,22 @@
    return color.pixel;
 }

+unsigned long
+getcolor_in_window(const char *colstr, Window w, unsigned long fallback) {
+   if (!w)
+       return fallback;
+   XWindowAttributes attr;
+   if (!XGetWindowAttributes(dpy, w, &attr))
+       return fallback;
+
+   Colormap cmap = attr.colormap;
+   XColor color;
+
+   if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
+       return fallback;
+   return color.pixel;
+}
+
 Bool
 getrootptr(int *x, int *y) {
    int di;
@@ -1144,7 +1161,7 @@

    wc.border_width = c->bw;
    XConfigureWindow(dpy, w, CWBorderWidth, &wc);
-   XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
+   XSetWindowBorder(dpy, w, getcolor_in_window(normbordercolor, w, dc.norm[ColBorder]));
    configure(c); /* propagates border_width, if size doesn't change */
    updatewindowtype(c);
    updatesizehints(c);
@@ -1776,7 +1793,7 @@
    if(!c)
        return;
    grabbuttons(c, False);
-   XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
+   XSetWindowBorder(dpy, c->win, getcolor_in_window(normbordercolor, c->win, dc.norm[ColBorder]));
    if(setfocus)
        XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
 }

The xmonad issue might be similar: (Code from xmonad-0.11)

XMonad/Operations.hs, line 422:

-- | Get the 'Pixel' value for a named color
initColor :: Display -> String -> IO (Maybe Pixel)
initColor dpy c = C.handle (\(C.SomeException _) -> return Nothing) $
    (Just . color_pixel . fst) <$> allocNamedColor dpy colormap c
    where colormap = defaultColormap dpy (defaultScreen dpy)

XMonad/Main.hsc, line 87:

    xinesc <- getCleanedScreenInfo dpy
    nbc    <- do v            <- initColor dpy $ normalBorderColor  xmc
                 ~(Just nbc_) <- initColor dpy $ normalBorderColor Default.defaultConfig
                 return (fromMaybe nbc_ v)

    fbc    <- do v <- initColor dpy $ focusedBorderColor xmc
                 ~(Just fbc_)  <- initColor dpy $ focusedBorderColor Default.defaultConfig
                 return (fromMaybe fbc_ v)

XMonad/Main.hsc, line 115:

        cf = XConf
            { display       = dpy
            , config        = xmc
            , theRoot       = rootw
            , normalBorder  = nbc
            , focusedBorder = fbc
            , keyActions    = keys xmc xmc
            , buttonActions = mouseBindings xmc xmc
            , mouseFocused  = False
            , mousePosition = Nothing
            , currentEvent  = Nothing }

But I can't provide a patch: Haskell isn't a traditional language and I don't have the time to learn it now.

ghost commented 8 years ago

Thanks for the hints for the XMonad code - I have cobbled together a fix, described in http://article.gmane.org/gmane.comp.lang.haskell.xmonad/14632