Frage

In my application, sometimes I need to disable most of the buttons and event boxes while a process is taking place (except the "cancel" button of course). Each event box contains a label which can be clicked. To make the user understand that these labels are clickable, I have underlined the texts and have made the cursor change when hovered over those labels.

The problem is that when I disable an event box (make it insensitive), you can see a rather ugly artifact:

enter image description here

So, I searched and found this function: gtk_event_box_set_visible_window. Note: I'm using (I have to, unfortunately) Gtk 2.22, but they just removed the documentation from their website. Anyway, the text of this function is the same.

According to this function, you can make the event box create a GDK_INPUT_ONLY window. If I do so, then disabling the event box doesn't make it ugly anymore.

However, since the event box now doesn't have an outputable window, the

gdk_window_set_cursor(event_box->window, cursor);

makes the cursor change for the whole window instead of just the event box.

I can somewhat see the contradiction between no visible window and cursor change over window, but my question is how, otherwise, can I have the cursor change over the event box, but don't see a visible artifact when the event box is disabled?

War es hilfreich?

Lösung

I tried different methods, such as changing the background of the event box to transparent etc, but all of them were quite complicated.

The simplest solution I found was the following:

static GdkCursor *_normal_cursor = NULL;
static GdkCursor *_hand_cursor = NULL;

/* in main */
    _normal_cursor = gdk_window_get_cursor(widgets_to_remember->window->window);
    _hand_cursor = gdk_cursor_new(GDK_HAND2);

    /* create the event box */
    gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box), FALSE);
    gtk_widget_set_events(event_box, GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);

    _fix_event_box(event_box, window);
/* rest of main */

static gboolean _set_hand(GtkWidget *w, GdkEventCrossing *e, gpointer data)
{
    gdk_window_set_cursor(w->window, _hand_cursor);
    return TRUE;
}

static gboolean _set_normal(GtkWidget *w, GdkEventCrossing *e, gpointer data)
{
    gdk_window_set_cursor(w->window, _normal_cursor);
    return TRUE;
}

static void _fix_event_box(GtkWidget *eb, GtkWidget *window)
{
    g_signal_connect_swapped(eb, "enter_notify_event", G_CALLBACK(_set_hand), window);
    g_signal_connect_swapped(eb, "leave_notify_event", G_CALLBACK(_set_normal), window);
}

What this basically does is set the event box invisible, and then set its enter-notify-event and leave-notify-event signal handlers to change the window cursor when the mouse enters or leaves their window.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top