LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-05-2008, 02:18 PM   #1
PatrickNew
Senior Member
 
Registered: Jan 2006
Location: Charleston, SC, USA
Distribution: Debian, Gentoo, Ubuntu, RHEL
Posts: 1,148
Blog Entries: 1

Rep: Reputation: 48
gtk window transparency


I'm getting a bit confused with this. The goal is to create a window so that when you pack things into it, the window itself is translucent, but the widgets in the window are not (unless that thing is an image with an alpha channel). I'm writing in gtkmm, but if anyone knows the answer in any other port of gtk, I can translate that back.

I thought Gtk::Window::set_opacity() was supposed to do this, but on my machine it does absolutely nothing (and yes, I'm running a compositing manager. I've got awn and screenlets running while I test, so I know it works) Gdk:isplay::supports_composite() is returning true on the display.

I found some other techniques that involved drawing on the windows Gdk::Window, but I think that those were pseudo-transparency hacks. I want to work with compositing.
 
Old 08-05-2008, 03:26 PM   #2
rocket357
Member
 
Registered: Mar 2007
Location: 127.0.0.1
Distribution: OpenBSD-CURRENT
Posts: 476
Blog Entries: 116

Rep: Reputation: 74
What value are you passing in to set_opacity()? Stupid question, I know, but I thought I'd ask =D
 
Old 08-05-2008, 04:30 PM   #3
ne pas
Member
 
Registered: Jul 2008
Posts: 55

Rep: Reputation: 23
Is your compositing manager running?

Following snippet works for me after I set "Visual Effects" to "Normal" or "Extra" in the appearance preferences ("System" -> "Preferences" -> "Appearance" -> "Visual Effects") [Ubuntu].
Code:
#include <gtk/gtk.h>

gint main(gint argc, gchar **argv)
{
  GtkWidget *window;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_window_set_opacity(GTK_WINDOW(window), 0.3);

  gtk_widget_show_all(window);

  gtk_main();
}
 
Old 08-05-2008, 06:25 PM   #4
PatrickNew
Senior Member
 
Registered: Jan 2006
Location: Charleston, SC, USA
Distribution: Debian, Gentoo, Ubuntu, RHEL
Posts: 1,148
Blog Entries: 1

Original Poster
Rep: Reputation: 48
@rocket357: I've tried 0, 1, and .5. No difference between them.

@ne_pas: The compositing manager is running. A 'ps -A' shows xcompmgr and both awn and screenlets are running with transparency. So this means that gtk_window_set_opacity should work, it's just not on my machine? I'll give it another shot and reply.
 
Old 08-05-2008, 06:36 PM   #5
PatrickNew
Senior Member
 
Registered: Jan 2006
Location: Charleston, SC, USA
Distribution: Debian, Gentoo, Ubuntu, RHEL
Posts: 1,148
Blog Entries: 1

Original Poster
Rep: Reputation: 48
Interesting. Your example code runs, but still gives me an opaque window. Just to clarify, I'm using openbox and xcompmgr. Hrm, I'll try again in Gnome and report back.
 
Old 08-05-2008, 06:43 PM   #6
PatrickNew
Senior Member
 
Registered: Jan 2006
Location: Charleston, SC, USA
Distribution: Debian, Gentoo, Ubuntu, RHEL
Posts: 1,148
Blog Entries: 1

Original Poster
Rep: Reputation: 48
Well, the exact same code behaves as expected on Metacity with compositing or on Compiz. I guess that probably makes this an xcompmgr bug.
 
Old 08-05-2008, 08:44 PM   #7
PatrickNew
Senior Member
 
Registered: Jan 2006
Location: Charleston, SC, USA
Distribution: Debian, Gentoo, Ubuntu, RHEL
Posts: 1,148
Blog Entries: 1

Original Poster
Rep: Reputation: 48
Hrm, well perhaps set_opacity isn't what I want. set_opacity() is also controlling the opacity of the widgets. For example, I create a transparent window, then pack a GtkLabel into it - the Label gets transparent with the window. Is there some other way of doing this?
 
Old 08-06-2008, 06:41 AM   #8
Su-Shee
Member
 
Registered: Sep 2007
Location: Berlin
Distribution: Slackware
Posts: 509

Rep: Reputation: 41
That's not a real bug of xcompmgr - xcompmgr is just rather old and was only meant to be a small design study to show that compositing works.

The difference is as far as I know that xcompmgr does not use the GLX_blahbla_whatever_pixmap thingie function Open GL compositing stuff as Compiz, metacity and Xfce uses. (Didn't exist at the time, xcompmgr seems to speak more directly with the graphic's layer...)

The appropriate test from within Gtk wether or not transparency / compositing is supported seems to depend exactly on this - that's why for example _some_ (not all) Cairo-based transparent gadgets like cairo clock or screenlets do not work.

And: If you need per-widget transparency within a Gtk app, you'll need an engine actually supporting this. There is none right now but the most recent SVN/CVS stuff of "murrine", the fancy Cairo-based Gtk-engine.

And I maybe totally wrong - it's really no fun to google in-depth information about all the transparency compositing gui widget foobar.

So, in short: Just use a more contemporary compositing manager. There's also a cairo-based one, but it depends on some Gnome stuff.

Addition: The combination of metisse and nucleo doesn't work either with most Gtk-stuff - the compositing mechanism is just not recognized.

Last edited by Su-Shee; 08-06-2008 at 06:44 AM.
 
Old 08-06-2008, 08:02 AM   #9
swift2008
Member
 
Registered: Jul 2008
Posts: 78

Rep: Reputation: 15
Quote:
Originally Posted by ne pas View Post
Is your compositing manager running?

Following snippet works for me after I set "Visual Effects" to "Normal" or "Extra" in the appearance preferences ("System" -> "Preferences" -> "Appearance" -> "Visual Effects") [Ubuntu].
Code:
#include <gtk/gtk.h>

gint main(gint argc, gchar **argv)
{
  GtkWidget *window;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  gtk_window_set_opacity(GTK_WINDOW(window), 0.3);

  gtk_widget_show_all(window);

  gtk_main();
}
hi

i am using fedora9
i run this program in my machine..
it is not working for me.

not showing any transaparency.
may i know the reasons for this.

and how can i overcome this problem

any help thanks inhand
 
Old 08-06-2008, 09:25 AM   #10
ne pas
Member
 
Registered: Jul 2008
Posts: 55

Rep: Reputation: 23
I hacked some stuff together for per-widget transparency, from various sources, it works at least with compiz and xcompmgr (never used bevor). My metacity (GNOME 2.20) has no build-in support for compositing, so although it has alpha-channel support, alpha will not be honored (see GdkScreen - gdk_screen_get_rgba_colormap).

gtk_transparent_window.c
Code:
#include <gtk/gtk.h>

static gboolean alpha_channel_support = FALSE;

static gboolean on_window_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
  cairo_t *cr;

  cr = gdk_cairo_create(widget->window); // create cairo context

  if(alpha_channel_support)
      // set source to RGB-Alpha
      cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.7);
  else
      // set source to RGB-Alpha
      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // set color RGB

  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // set drawing compositing operator
                                                 // SOURCE -> replace destination

  cairo_paint(cr); // paint source

  cairo_destroy(cr);

  return FALSE;
}

gint main(gint argc, gchar **argv)
{
  GtkWidget *window, *button, *vbox;
  GdkScreen *screen;
  GdkColormap *colormap;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL);
  g_signal_connect(G_OBJECT(window), "expose-event", G_CALLBACK(on_window_expose_event), NULL);

  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);

  gtk_widget_set_app_paintable(window, TRUE); // allow application to paint on widget

  screen = gtk_widget_get_screen(window);

  colormap = gdk_screen_get_rgba_colormap(screen); // get colormap with alpha channel

  if(colormap != NULL)
  {
      alpha_channel_support = TRUE;
  }
  else
  {
      alpha_channel_support = FALSE;

      colormap = gdk_screen_get_rgb_colormap(screen);

      g_message("Screen supports no alpha channels\n");
  }

  gtk_widget_set_colormap(window, colormap);

  button = gtk_button_new();
  gtk_button_set_label(GTK_BUTTON(button), "Don't Press!");

  vbox = gtk_vbox_new(TRUE, 5);
  gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 5);

  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox));

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}
 
Old 08-06-2008, 09:38 AM   #11
ne pas
Member
 
Registered: Jul 2008
Posts: 55

Rep: Reputation: 23
Quote:
Originally Posted by swift2008 View Post
not showing any transaparency.
may i know the reasons for this.

and how can i overcome this problem
You need to have a compositing manager running, like compiz, xcompmgr or metacity (has built-in compositing since GNOME v2.22).
 
Old 09-06-2008, 01:23 PM   #12
phorgan1
LQ Newbie
 
Registered: May 2008
Posts: 9

Rep: Reputation: 0
Question Background image with alpha

Quote:
Originally Posted by ne pas View Post
I hacked some stuff together for per-widget transparency ... stuff elided ...
Thank you. Your code worked great for me until---I wanted to try to put a background with alpha into the transparent window. The background showed up fine before I added your code, but the transparent parts weren't. Then I added your code and the background is as transparent as I want to make it, but the background image is gone. Help!!! Here's my code, (much stolen directly from you

Code:
#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <stdlib.h>

GtkWidget *window;
static gboolean alpha_channel_support = FALSE;

static gboolean
expose_window(GtkWidget *widget, GdkEventExpose *event, gpointer date)
    {
    cairo_t *cr;

    cr = gdk_cairo_create(widget->window); /* create cairo context */

    if(alpha_channel_support){
    /* set source to RGB-Alpha */
        cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, .6);
        g_print("got alpha in expose");
    }else{
    /* set source to RGB-Alpha */
        cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); /* set color RGB */
    }

    /* set drawing compositing operator */
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    /* SOURCE -> replace destination */

    cairo_paint(cr); /* paint source */

    cairo_destroy(cr);

    return FALSE;
}

int
setupwindow()
{
    GdkPixmap *background;
    GdkPixbuf *pixbuf;
    GdkPixbuf *scaled;
    GdkScreen *screen;
    GdkColormap *colormap;
    GError *error=NULL;
    GtkStyle *style;
    gboolean boolit;

    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(G_OBJECT(window), "expose_event", G_CALLBACK(expose_window),NULL);
    gtk_window_set_title(GTK_WINDOW(window), "clock");
    gtk_window_stick(GTK_WINDOW(window));
    gtk_window_set_resizable(GTK_WINDOW(window),TRUE);
    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(window),TRUE);
    gtk_window_set_keep_above(GTK_WINDOW(window),TRUE);
    gtk_container_set_border_width(GTK_CONTAINER(window), 3);
    gtk_window_set_decorated(GTK_WINDOW(window),TRUE);
    gtk_window_set_default_size(GTK_WINDOW(window),100,100);
    gtk_widget_set_app_paintable(window,TRUE);

    /* Get the screen to get the colormap */
    screen=gtk_widget_get_screen(window);
    colormap = gdk_screen_get_rgba_colormap(screen);
    if(colormap != NULL){
        alpha_channel_support=TRUE;
    } else {
        alpha_channel_support=FALSE;
        colormap=gdk_screen_get_rgb_colormap(screen);
        g_print("Sorry, no alpha!\n");
    }
    /* Tell the window to use the colormap */
    gtk_widget_set_colormap(window,colormap);

    /* Get a pixbuf from the image file */
    pixbuf=gdk_pixbuf_new_from_file("clockface.png",&error);

    if(pixbuf==NULL){
        g_print("Failed to open background image: %s\n", error->message);
        g_error_free(error);
        error=NULL;
        return 0;
    }
    /* Make it the same size as the window */
    scaled=gdk_pixbuf_scale_simple(pixbuf,100,100, GDK_INTERP_BILINEAR);
    /* Render it using the colormap of the window */
    gdk_pixbuf_render_pixmap_and_mask_for_colormap(scaled,colormap,&background,NULL,0);
    /* Make a new style, stick the background in it, tell window to use it. */
    style = gtk_style_new();
    style->bg_pixmap[0] = background;
    gtk_widget_set_style(GTK_WIDGET(window),GTK_STYLE(style));

    /*gtk_window_set_opacity(GTK_WINDOW(window),0.3);*/
    gtk_window_move(GTK_WINDOW(window), 0, 0);
    gtk_widget_show_all(window);
    return 1;
}

int
main(int argc, char **argv)
{
    gtk_init(&argc,&argv);
    if(!setupwindow()){
        exit(EXIT_FAILURE);
    }
    gtk_main();
    exit(EXIT_SUCCESS);
}
Does anyone have any idea how I can get a background image with alpha to work? What I'm trying to do eventually is to make a free floating clock with only the face showing. (Even better if it's notification area icon would dynamically keep the time when the application is not showing I know it can be done from X, but how do you do in in GDK/GTK?

Patrick
 
Old 09-08-2008, 12:23 PM   #13
PatrickNew
Senior Member
 
Registered: Jan 2006
Location: Charleston, SC, USA
Distribution: Debian, Gentoo, Ubuntu, RHEL
Posts: 1,148
Blog Entries: 1

Original Poster
Rep: Reputation: 48
I've done stuff like that before, and I found it much easier to use a shaped window instead of transparency. Look at gdk_window_shape_combine_mask, that's probably what you want.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can Gtk have transparency like WINDOWS VISTA please ?? Xeratul General 32 06-06-2007 01:01 PM
Gnome transparency + window manager keratos Ubuntu 2 05-19-2007 02:40 AM
Window Transparency effects bonito Suse/Novell 18 11-30-2006 10:25 PM
Python transparency in window ElementNine Programming 1 01-21-2004 01:29 AM


All times are GMT -5. The time now is 05:43 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration