How to have a window closed when a user clicks outside of it using GTK+2?

287 views Asked by At

I was wondering if there is any simple way for closing a window when a user clicks out side of it (so it becomes out of focus).

For example I have this window here:

static void applauncher_create_window(AppLauncherPlugin * pALP)
{
    FmIcon * fm_icon;
    GdkPixbuf * pixbuf;
    GtkWidget * icon_view;
    GtkWidget * scrolled_window;
    GtkWidget * win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    GtkWidget * vbox;
    GtkTreeModel * tree_model;
    //GtkWidget * fileBtn;
    //GtkWidget * picBtn;
    //GtkWidget * musicBtn;
    GtkWidget * button;
    GtkWidget * image;
    GtkWidget * label;
    GtkWidget * hbox;
    GtkWidget * innerVbox;
    GtkWidget * alignment;

    gtk_window_maximize(GTK_WINDOW(win));
    vbox = gtk_vbox_new(FALSE,0);
    alignment = gtk_alignment_new(0.5, 0.5, 0,0);
    /*picBtn = gtk_button_new();
    musicBtn = gtk_button_new();
    vidBtn = gtk_button_new();*/

    gtk_window_set_decorated(GTK_WINDOW(win), FALSE);
    gtk_window_set_skip_taskbar_hint(GTK_WINDOW(win), TRUE);
    gtk_window_set_skip_pager_hint(GTK_WINDOW(win), TRUE);

    hbox = gtk_hbox_new(FALSE, 0);

    button = gtk_button_new();
    innerVbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(button),innerVbox);
    fm_icon = fm_icon_from_name("sr-applauncher-files");
    pixbuf = fm_pixbuf_from_icon(fm_icon, pALP->app_icon_size);
    if (fm_icon)
        g_object_unref(fm_icon);
    image = gtk_image_new_from_pixbuf(pixbuf);
    if (pixbuf)
        g_object_unref(pixbuf);
    label = gtk_label_new("Files");
    gtk_box_pack_start(GTK_BOX(innerVbox), image, FALSE,FALSE,0);
    gtk_box_pack_start(GTK_BOX(innerVbox), label, FALSE,FALSE,0);
    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
    g_signal_connect(button, "clicked", G_CALLBACK(files_folder),pALP);
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE,FALSE,0);


    button = gtk_button_new();
    innerVbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(button),innerVbox);
    fm_icon = fm_icon_from_name("sr-applauncher-music");
    pixbuf = fm_pixbuf_from_icon(fm_icon, pALP->app_icon_size);
    if (fm_icon)
        g_object_unref(fm_icon);
    image = gtk_image_new_from_pixbuf(pixbuf);
    if (pixbuf)
        g_object_unref(pixbuf);
    label = gtk_label_new("Music");
    gtk_box_pack_start(GTK_BOX(innerVbox), image, FALSE,FALSE,0);
    gtk_box_pack_start(GTK_BOX(innerVbox), label, FALSE,FALSE,0);
    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
    g_signal_connect(button, "clicked", G_CALLBACK(music_folder), pALP);
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE,FALSE,0);

    button = gtk_button_new();
    innerVbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(button),innerVbox);
    fm_icon = fm_icon_from_name("sr-applauncher-pictures");
    pixbuf = fm_pixbuf_from_icon(fm_icon, pALP->app_icon_size);
    if (fm_icon)
        g_object_unref(fm_icon);
    image = gtk_image_new_from_pixbuf(pixbuf);
    if (pixbuf)
        g_object_unref(pixbuf);
    label = gtk_label_new("Pictures");
    gtk_box_pack_start(GTK_BOX(innerVbox), image, FALSE,FALSE,0);
    gtk_box_pack_start(GTK_BOX(innerVbox), label, FALSE,FALSE,0);
    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
    g_signal_connect(button, "clicked", G_CALLBACK(pictures_folder), pALP);
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE,FALSE,0);


    button = gtk_button_new();
    innerVbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(button),innerVbox);
    fm_icon = fm_icon_from_name("sr-applauncher-videos");
    pixbuf = fm_pixbuf_from_icon(fm_icon, pALP->app_icon_size);
    if (fm_icon)
        g_object_unref(fm_icon);
    image = gtk_image_new_from_pixbuf(pixbuf);
    if (pixbuf)
        g_object_unref(pixbuf);
    label = gtk_label_new("Videos");
    gtk_box_pack_start(GTK_BOX(innerVbox), image, FALSE,FALSE,0);
    gtk_box_pack_start(GTK_BOX(innerVbox), label, FALSE,FALSE,0);
    gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
    g_signal_connect(button, "clicked", G_CALLBACK(videos_folder), pALP);
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE,FALSE,0);


    gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE,FALSE,0);
    gtk_container_add(GTK_CONTAINER(alignment), hbox);


    scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE,TRUE,0);
    gtk_container_add(GTK_CONTAINER(win), vbox);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN);

    icon_view = gtk_icon_view_new_with_model(create_and_fill_model(pALP));
    g_object_unref(pALP->list_store);       /* destroy model automatically with view */
    gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view), GTK_SELECTION_SINGLE);
    gtk_icon_view_set_reorderable(GTK_ICON_VIEW(icon_view), TRUE);
    gtk_icon_view_set_text_column(GTK_ICON_VIEW(icon_view), COL_DISPLAY_NAME);
    gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view), COL_PIXBUF);
    gtk_icon_view_set_tooltip_column(GTK_ICON_VIEW(icon_view), COL_TOOLTIP);
    //g_signal_connect(icon_view, "button-press-event", G_CALLBACK(icon_view_onButtonPressed), pALP);

    tree_model = gtk_icon_view_get_model(GTK_ICON_VIEW(icon_view));
    g_signal_connect(icon_view, "item-activated", G_CALLBACK(icon_view_onItemActivated), pALP);

    g_signal_connect(win, "destroy", G_CALLBACK(appluncher_store_state), pALP);

    //gtk_tree_model_foreach(GTK_TREE_MODEL(pALP->list_store), foreach_func, pALP);

    //_menu_cache_lookup_sync("appLuncher.menu");

    gtk_container_add(GTK_CONTAINER(scrolled_window), icon_view);

    gtk_widget_show_all(scrolled_window);

    pALP->applauncher_window = win;

}

I am currently thinking of setting transient and gtk_widgets_set_even(widget, GDK_MASK_FOCUS_CHANGEd).

Is there any other way as this will assumably work on popups but my window doesn't contain pop ups.

1

There are 1 answers

0
Julian Lazaras On

I would think that using another library to get general mouse information, would work best, for example curses something like this:

#include<curses.h>
GSList* List; //This is a singly linked list provided by glib as well.
g_timeout_add_seconds(1, callback, List);
void callback(void* pointer){
    MEVENT event;
    ch = getch();
    if(ch == KEY_MOUSE){
        if(getmouse(&event) == OK){
            /* Do some thing with the event */
       }
    }
} 

use the list to store any widgets that you will be altering