Как закрыть окно, когда пользователь щелкает за его пределами, используя GTK + 2?

Мне интересно, есть ли какой-нибудь простой способ закрыть окно, когда пользователь щелкает за его пределами (так что оно становится не в фокусе).

Например, у меня есть это окно здесь:

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;

}

В настоящее время я думаю о настройке переходного процесса и gtk_widgets_set_even(widget, GDK_MASK_FOCUS_CHANGEd).

Есть ли другой способ, поскольку это, вероятно, будет работать с всплывающими окнами, но мое окно не содержит всплывающих окон.


person Barr J    schedule 10.06.2015    source источник
comment
Вы придумали какое-нибудь решение?   -  person Mateusz Piotrowski    schedule 15.06.2015
comment
Я считаю, что ваша маска изменения в сочетании с обработчиком сигнала для события focus-out должна помочь.   -  person Mike    schedule 17.06.2015
comment
Пока нет решения, мое окно не принимает фокус и никогда не будет, поскольку оно развернуто до такой степени, что видна только панель lxde. это означает, что при нажатии на lxpanel он закроется. В этом и загвоздка, нужно проверить, щелкнул ли пользователь за пределы окна, без фокуса. Координаты X, Y или попробуйте передать LXpanel в качестве параметра, но это приведет к сегментации.   -  person Barr J    schedule 17.06.2015


Ответы (1)


Я бы подумал, что использование другой библиотеки для получения общей информации о мыши будет работать лучше всего, например, curses примерно так:

#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 */
       }
    }
} 

используйте список для хранения любых виджетов, которые вы будете изменять

person Julian Lazaras    schedule 19.07.2019