You are not logged in.

#1 2009-05-09 13:10:33

Dieter@be
Forum Fellow
From: Belgium
Registered: 2006-11-05
Posts: 2,001
Website

[Solved] standalone Gtk dialog: how to keep it above other windows?

i'm building a zenity-like program ( http://bbs.archlinux.org/viewtopic.php?id=71453 )
For some reason my WM (wmii) always treats it as a "full window" unlike zenity which is a small popup.
I want to have it behave like zenity.  I studied the zenity source code but they use Glade which makes it hard to grasp.

i also made a test program to try out a variety of options, but all my attempts failed.
The attempts that need the root window failed because I couldn't figure out the correct way to get the root window. (apparently GDK_ROOT_PARENT(); does not work. I get glib assertion errors)

#include <gtk/gtk.h>

int main( int argc, char *argv[])
{
  GtkWidget *window;

  gtk_init(&argc, &argv);

 GtkWidget * root =  (GtkWidget *) GDK_ROOT_PARENT();
/* this is supposed to call gtk_window_set_type_hint() automatically
GtkWidget *dialog = gtk_dialog_new_with_buttons ("My dialog",
                                                  (GtkWindow *) root,
                                                  GTK_DIALOG_MODAL,
                                                  "title");
 */
  window = gtk_dialog_new();
  gtk_window_set_transient_for ((GtkWindow *)window, (GtkWindow *)root);
  gtk_window_set_keep_above ( (GtkWindow *) window, TRUE);
//gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
  //gtk_window_set_title(GTK_WINDOW(window), "Center");
 // gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
//  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_widget_show(window);

  g_signal_connect_swapped(G_OBJECT(window), "destroy",
      G_CALLBACK(gtk_main_quit), NULL);

  gtk_main();

  return 0;
}

Last edited by Dieter@be (2009-05-13 19:17:20)


< Daenyth> and he works prolifically
4 8 15 16 23 42

Offline

#2 2009-05-11 19:04:31

kumyco
Member
From: somewhere
Registered: 2008-06-23
Posts: 153
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

GDK_ROOT_PARENT() is a (deprecated) macro to gdk_get_default_root_window() which returns a gdk window as opposed to a gtk window, therefore it cannot be passed to gtk_window_set_transient_for, that's used to put a window on top of another.
it should suffice to use just, gtk_window_set_keep_above .. it appears to work just fine in the example below.
it's common practice to utilize the g*k casting macros such as GTK_WINDOW() as opposed to (GtkWindow*) it will prove very useful as it flags incompatible casts (at runtime)

#include <gtk/gtk.h>

int main(int argc, char **argv)
{
    GtkWidget *parent, *dialog;
    
    gtk_init(&argc, &argv);
    
    parent = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    dialog = gtk_dialog_new_with_buttons("My dialog", GTK_WINDOW(parent),
      /* note the button text 'title', response id, and terminating NULL */
      GTK_DIALOG_MODAL, "title", GTK_RESPONSE_NONE, NULL);
    
    /* keep dialog above parent */
    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
    /* keep parent above all other normal windows, 'Always on Top in some WM' */
    gtk_window_set_keep_above(GTK_WINDOW(parent), TRUE);
    
    gtk_window_set_title(GTK_WINDOW(parent), "Center");
    gtk_window_set_default_size(GTK_WINDOW(parent), 230, 150);
    gtk_window_set_position(GTK_WINDOW(parent), GTK_WIN_POS_CENTER);
    
    gtk_widget_show(parent);
    gtk_widget_show(dialog);
    
    g_signal_connect(G_OBJECT(parent), "delete-event",
      G_CALLBACK(gtk_main_quit), NULL);
    
    gtk_main();
    
    return 0;
}

let me know i need comment on anything

Last edited by kumyco (2009-05-11 19:05:45)

Offline

#3 2009-05-11 19:16:31

Dieter@be
Forum Fellow
From: Belgium
Registered: 2006-11-05
Posts: 2,001
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

kumyco wrote:

GDK_ROOT_PARENT() is a (deprecated) macro to gdk_get_default_root_window() which returns a gdk window as opposed to a gtk window, therefore it cannot be passed to gtk_window_set_transient_for, that's used to put a window on top of another.
it should suffice to use just, gtk_window_set_keep_above .. it appears to work just fine in the example below.
it's common practice to utilize the g*k casting macros such as GTK_WINDOW() as opposed to (GtkWindow*) it will prove very useful as it flags incompatible casts (at runtime)

#include <gtk/gtk.h>

int main(int argc, char **argv)
{
    GtkWidget *parent, *dialog;
    
    gtk_init(&argc, &argv);
    
    parent = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    dialog = gtk_dialog_new_with_buttons("My dialog", GTK_WINDOW(parent),
      /* note the button text 'title', response id, and terminating NULL */
      GTK_DIALOG_MODAL, "title", GTK_RESPONSE_NONE, NULL);
    
    /* keep dialog above parent */
    gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
    /* keep parent above all other normal windows, 'Always on Top in some WM' */
    gtk_window_set_keep_above(GTK_WINDOW(parent), TRUE);
    
    gtk_window_set_title(GTK_WINDOW(parent), "Center");
    gtk_window_set_default_size(GTK_WINDOW(parent), 230, 150);
    gtk_window_set_position(GTK_WINDOW(parent), GTK_WIN_POS_CENTER);
    
    gtk_widget_show(parent);
    gtk_widget_show(dialog);
    
    g_signal_connect(G_OBJECT(parent), "delete-event",
      G_CALLBACK(gtk_main_quit), NULL);
    
    gtk_main();
    
    return 0;
}

let me know i need comment on anything

Thanks, but like i said I'm trying to make a standalone dialog program (similar to zenity).  Your dialog looks okay but you need a parent window.  The parent window in my case should be the root window i believe.


< Daenyth> and he works prolifically
4 8 15 16 23 42

Offline

#4 2009-05-11 20:21:29

kumyco
Member
From: somewhere
Registered: 2008-06-23
Posts: 153
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

parent window for what, i don't quite understand -- zenity is like dialog, but for gtk yes?
you pass different parameters and it creates dialogs based on that, the dialog is a window with widgets on there, buttons, etc.
do you mean, the dialog without the normal window? it's not needed i just fixed up your example, including the commented out bits

Offline

#5 2009-05-11 20:38:46

Dieter@be
Forum Fellow
From: Belgium
Registered: 2006-11-05
Posts: 2,001
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

kumyco wrote:

parent window for what, i don't quite understand -- zenity is like dialog, but for gtk yes?
you pass different parameters and it creates dialogs based on that, the dialog is a window with widgets on there, buttons, etc.
do you mean, the dialog without the normal window? it's not needed i just fixed up your example, including the commented out bits

Yes, zenity is like dialog, but for gtk.
Indeed I only need the dialog, not any other window.  Your example creates a window and the dialog as child on it, which is not what i want

Last edited by Dieter@be (2009-05-11 20:39:15)


< Daenyth> and he works prolifically
4 8 15 16 23 42

Offline

#6 2009-05-11 21:59:40

kumyco
Member
From: somewhere
Registered: 2008-06-23
Posts: 153
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

a more complete example, also demonstrates how you can add your own stuff to the dialog

#include <gtk/gtk.h>

void on_response (GtkDialog *dialog, gint response, gpointer data);

int main(int argc, char **argv)
{
    GtkWidget *dialog, *content, *label, *box, *image;
    
    gtk_init(&argc, &argv);
    
    dialog = gtk_dialog_new();
    gtk_window_set_title(GTK_WINDOW(dialog), "Center");
    gtk_window_set_default_size(GTK_WINDOW(dialog), 230, 150);
    gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
    gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
    
    gtk_window_set_skip_pager_hint(GTK_WINDOW(dialog), TRUE);
    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), TRUE);
    
    gtk_dialog_add_button(GTK_DIALOG(dialog), "title", GTK_RESPONSE_ACCEPT);
    gtk_dialog_add_button(GTK_DIALOG(dialog), "(11) Ok", 11);
    
    /* the vbox that holds the content_area */
    content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    box = gtk_hbox_new(FALSE, 0);
    label = gtk_label_new("Hello, World!");
    image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
    gtk_container_add(GTK_CONTAINER(box), image);
    gtk_container_add(GTK_CONTAINER(box), label);
    gtk_container_add(GTK_CONTAINER(content), box);
    
    /* emitted when the window is closed */
    g_signal_connect(G_OBJECT(dialog), "delete-event", G_CALLBACK(gtk_main_quit), NULL);
    
    /* emitted when a button is clicked */
    g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(on_response), NULL);
    
    gtk_widget_show_all(dialog);
    gtk_main();
    
    return 0;
}


void on_response (GtkDialog *dialog, gint response, gpointer data)
{
    GtkWidget *label;
    
    (void)data;
    
    switch (response) {
        case GTK_RESPONSE_ACCEPT:
            /* what to do when this signal is received */
            g_print("you clicked on title\n");
            break;
        case 11:
            /* ... */
            gtk_main_quit();
            break;
    }
}

Last edited by kumyco (2009-05-12 21:17:14)

Offline

#7 2009-05-12 19:52:28

Dieter@be
Forum Fellow
From: Belgium
Registered: 2006-11-05
Posts: 2,001
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

kumyco wrote:

a more complete example, also demonstrates how you can add your own stuff to the dialog

Thanks.  But unfortunately this also shows as a "full" application in my wm (wmii), unlike zenity which is just a small floating dialog.


< Daenyth> and he works prolifically
4 8 15 16 23 42

Offline

#8 2009-05-12 21:19:33

kumyco
Member
From: somewhere
Registered: 2008-06-23
Posts: 153
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

oops, forgot those
added pager and taskbar skip hints, also don't forget you may need to take care of memory management
each _new needs a  g_unref if you get rid of the widgets and keep the app running

Offline

#9 2009-05-13 18:21:27

Dieter@be
Forum Fellow
From: Belgium
Registered: 2006-11-05
Posts: 2,001
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

kumyco wrote:

oops, forgot those
added pager and taskbar skip hints, also don't forget you may need to take care of memory management
each _new needs a  g_unref if you get rid of the widgets and keep the app running

still the same problem sad


< Daenyth> and he works prolifically
4 8 15 16 23 42

Offline

#10 2009-05-13 18:52:52

Dieter@be
Forum Fellow
From: Belgium
Registered: 2006-11-05
Posts: 2,001
Website

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

Robm told me to use:

static void
make_transient (GtkWidget *win)
{
  GdkScreen *screen;
  GdkWindow *root;
 
  /* Make window transient for the root window */
  screen = gdk_screen_get_default();
  root = gdk_screen_get_root_window(screen);
  gdk_window_set_transient_for(win->window, root);
 
}

which works great smile


< Daenyth> and he works prolifically
4 8 15 16 23 42

Offline

#11 2009-05-13 18:56:14

Wra!th
Member
Registered: 2009-03-31
Posts: 342

Re: [Solved] standalone Gtk dialog: how to keep it above other windows?

Dieter@be wrote:
kumyco wrote:

oops, forgot those
added pager and taskbar skip hints, also don't forget you may need to take care of memory management
each _new needs a  g_unref if you get rid of the widgets and keep the app running

still the same problem sad

Did you stop to wonder that it might be your WM's fault?
I suggest you get back to studying how zenity does it's transient stuff, because your first code is more or less correct, It's the WM that doesn't let it act as it should (using Ratpoison here and the window shows as a normal dialog...not maximised)

_NET_WM_WINDOW_TYPE_DIALOG is the only thing needed btw...No need to set transients...dialogs should be treated as such by any WM...
This works just fine.

#include <gtk/gtk.h>

int main( int argc, char *argv[])
{
    GtkWidget *window;
    gtk_init(&argc, &argv);
    window = gtk_dialog_new();

    gtk_window_set_keep_above ( (GtkWindow *) window, TRUE);
    gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_DIALOG);
    gtk_window_set_title(GTK_WINDOW(window), "Center");
    gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_widget_show(window);

    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

    gtk_main();
    return 0;
}

Last edited by Wra!th (2009-05-13 19:07:29)


MacGregor DESPITE THEM!
7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Offline

Board footer

Powered by FluxBB