Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintaining 100% Opacity of the Content in a Transparent Menu (w/ example) #286

Open
quadpixels opened this issue May 13, 2015 · 4 comments

Comments

@quadpixels
Copy link

Hello Compton,
I love Compton so much, especially the gorgeous blur effects acted upon transparent menus/windows!
I think there is a little improvement that can be made to the Transparent Menus. (I don't know if this already exists in a fork or not, so if there is one please delete this issue)
When a menu is made transparent, all of its pixels are made transparent, regardless of whether a pixel is content or background. This means when you set the menu opacity to a very low value, you may not be able to easily see the text and icons on the menu. (See the picture)

example

I think a simple way to make the contents opaque is through the usage of the custom shader (The one used in the --glx-fshader-win flag.) If we only make the background menu colors transparent, we can obtain the effects in the second picture.
The custom shader looks like the following:

uniform float opacity;
uniform bool invert_color;
uniform sampler2D tex;
void main() {
  vec4 c = texture2D(tex, gl_TexCoord[0]);
  float eps = 0.018f;
  float eps1 = 0.0f;
  if (invert_color)
     c = vec4(vec3(c.a, c.a, c.a) - vec3(c), c.a);
  if(
  (c.r > 0.807843+eps1-eps && c.r < 0.807843+eps1+eps &&
   c.g > 0.807843+eps1-eps && c.g < 0.807843+eps1+eps &&
   c.b > 0.807843+eps1-eps && c.b < 0.807843+eps1+eps) ||
  (c.r > 0.953255+eps1-eps && c.r < 0.953255+eps1+eps &&
   c.g > 0.953255+eps1-eps && c.g < 0.953255+eps1+eps &&
   c.b > 0.953255+eps1-eps && c.b < 0.953255+eps1+eps)
  ) { c *= opacity; } 
  else {  }
  gl_FragColor = c;
}

The color values (0.953255, 0.953255, 0.953255) (0xFCFCFC) and (0.807843, 0.807843, 0.807843) (0xCECECE) are the "menu background color" and "normal background color" (used in Whisker Menu) of the XFCE GreyBird GTK3 theme. The eps value is determined using personal experience and may need more reasoning.

However, there is a catch in using colors: it stops working when the background of menu is not a solid color. I could be wrong, but I assume there is not an easy way to differentiate the background and the foreground as the information is lost when the content of the menu is handed to Compton in the form of a bitmap? Anyway the "color hack" seems to work well for me as of now.

This involved changing 3 files; the following is not elegant and it adds a dependency (GTK3) , but it demonstrates the idea.
I added a flag called --tommy-flag, and you can run compton with this new flag to see the results.

Hope this may be useful and thanks so much!
quadpixels
(p.s. I'm not sure if this is the correct place to post this, so you may remove this issue if I'm wrong)

-----------------------Appendix--------------------------

diff compton-my/src/common.h gitrepo/compton/src/common.h 
579,581d578
< 
<   bool tommy_flag;  // Grab BG color from GTK settings and use them on the custom shader
< 
diff compton-my/src/compton.c gitrepo/compton/src/compton.c
14,17d13
< // Hack: Automatically fetch the normal background and menu background colors
< #include <gtk-3.0/gtk/gtk.h>
< #include <gtk-3.0/gdk/gdk.h>
< 
5755d5750
<   { "tommy-flag", no_argument, NULL, 321 },
6026,6085d6020
<     case 321: {
<         ps->o.tommy_flag = true;
<       gtk_init(NULL, NULL);
<       GdkRGBA bg_color_win, bg_color_menu;
<       GtkWidget* win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
<       GtkStyleContext* ctxt = gtk_widget_get_style_context(win);
<       gtk_style_context_get_background_color(ctxt, GTK_STATE_FLAG_NORMAL, &bg_color_win);
<       gtk_widget_destroy(win);
<       GtkWidget* menu = gtk_menu_new();
<       ctxt = gtk_widget_get_style_context(menu);
<       gtk_style_context_get_background_color(ctxt, GTK_STATE_FLAG_NORMAL, &bg_color_menu);
<       gtk_widget_destroy(menu);
<       printf("I have got some colors from GTK! (%g,%g,%g) and (%g,%g,%g)\n",
<           bg_color_win.red, bg_color_win.green, bg_color_win.blue,
<           bg_color_menu.red,bg_color_menu.green,bg_color_menu.blue);
<       const int N = 2;
<       double x[2][3] = { { 0.807, 0.807, 0.807 }, { 0.953, 0.953, 0.953 } };
<       x[0][0] = bg_color_win.red; x[0][1] = bg_color_win.green; x[0][2] = bg_color_win.blue;
<       x[1][0] = bg_color_menu.red;x[1][1] = bg_color_menu.green;x[1][2] = bg_color_menu.blue;
<       const char* part1 = 
<           "uniform float opacity;\n"
<           "uniform bool invert_color;\n"
<           "uniform sampler2D tex;\n"
<           "void main() {\n"
<           "  vec4 c = texture2D(tex, gl_TexCoord[0]);\n"
<           "  float eps = 0.018f;\n"
<           "  float eps1 = 0.0f;\n"
<           "  if (invert_color)\n"
<           "    c = vec4(vec3(c.a, c.a, c.a) - vec3(c), c.a);\n"
<           "  if(";
< 
<       char tmp[200], conditions[2000];
<       int offset = 0;
<       for(int n=0; n<N; n++) {
<           double red = x[n][0], green = x[n][1], blue = x[n][2];
<           sprintf(tmp, "  (c.r > %g+eps1-eps && c.r < %g+eps1+eps &&\n"
<               "   c.g > %g+eps1-eps && c.g < %g+eps1+eps &&\n"
<               "   c.b > %g+eps1-eps && c.b < %g+eps1+eps)",
<               red, red, green, green, blue, blue);
<           if (n < N-1) {
<               unsigned l = strlen(tmp);
<               sprintf(tmp+l, " ||\n");
<           }
<           
<           sprintf(conditions + offset, "%s", tmp);
<           offset += strlen(tmp);
<       }
< 
<       const char* part2 = 
<           "  ) { c *= opacity; } \n"
<           "  else {  }\n"
<           "  gl_FragColor = c;\n"
<           "}\n";
< 
<       char* big = (char*)malloc(10000);
<       sprintf(big, "%s\n%s\n%s", part1, conditions, part2);
<       ps->o.glx_fshader_win_str = mstrcpy(big);
<       free(big);
<       break;
<     }
diff compton-my/Makefile gitrepo/compton/Makefile 
12,13c12,13
< LIBS = -lm -lrt $(shell pkg-config --libs gtk+-3.0)
< INCS = $(shell pkg-config --cflags gtk+-3.0)

---
> LIBS = -lm -lrt
> INCS =
@quadpixels quadpixels changed the title Maintaining 100% Opacity of the Content in a Transparent Menu Maintaining 100% Opacity of the Content in a Transparent Menu (w/ example) May 13, 2015
@actionless
Copy link

how it will work with a gradiented background?

@quadpixels
Copy link
Author

If you ask "how to make it work with gradiented background", the conditions in the shader need to be made to match all the colors in the gradient. It's like determining whether a point is on a line segment...

@blueyed
Copy link

blueyed commented Jul 8, 2015

@quadpixels
That sounds very useful!

Could you create a pull request (from a separate branch in your fork) for this?
This makes it easier to discuss/review/test the code.

@quadpixels
Copy link
Author

@blueyed
Thanks for the advice! It does look better to use the pull request feature than posting an issue.
I just created pull request #295 . The code should compile, although it is not of "production-ready" level quality. I think getting this feature done perfectly is beyond my knowledge right now, so I am also looking forward to learning from discussions/reviews//tests.

tryone144 pushed a commit to tryone144/compton that referenced this issue Jan 22, 2020
Parse `--blur-*` options as documented in manpage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants