Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 27/06/2012, à 22:16

Tangram

C + GTK3 : Èvénements focus perdus pour les grandes fenêtres

J'ai fait un petit test sur Ubuntu 12.04 :

Je veux utiliser les événements "focus-in-event" et "focus-out-event". Je lance le programme de test depuis un Terminal, je déplace la fenêtre, je l'active/désactive, je l'iconifie/désiconifie, les événements focus sont bien repérés.

Lorsque j'augmente la taille de la fenêtre (pour moi au moins 700x450), au bout de quelques manipulations comme cité plus haut, le repérage des événements focus s’arrête. Pourtant, les signaux sont toujours connectés.

Il semble que l'icônification de la fenêtre soit le principal déclencheur du phénomène, et que les déplacement/activation/désactivation soient des agents préparateurs.

J'aimerais savoir ce que vous en pensez.
Et toutes mes excuses par avance si le sujet a déjà été traité.

Le programme de test :

#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>

#define WINDOW_WIDTH   200
#define WINDOW_HEIGHT  150

static GtkWidget *window;
static gulong focus_in_id;
static gulong focus_out_id;

static gboolean
focus_in_event (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    printf ("F"); fflush (stdout);
    return FALSE;
    (void)widget;
    (void)event;
    (void)user_data;
}

static gboolean
focus_out_event (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    printf ("f"); fflush (stdout);
    return FALSE;
    (void)widget;
    (void)event;
    (void)user_data;
}

static gboolean
delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    gboolean focus_in  = g_signal_handler_is_connected (G_OBJECT (window), focus_in_id);
    gboolean focus_out = g_signal_handler_is_connected (G_OBJECT (window), focus_out_id);
    gint focus_change  = gtk_widget_get_events (window) & GDK_FOCUS_CHANGE_MASK;

    printf ("\n");
    printf ("focus-in-event   : %s\n", (focus_in!=0) ? "connected" : "disconnected");
    printf ("focus-out-event  : %s\n", (focus_out!=0) ? "connected" : "disconnected");
    printf ("GDK_FOCUS_CHANGE : %s\n", (focus_change!=0) ? "set" : "clear");
    gtk_main_quit ();
    return FALSE;
    (void)widget;
    (void)event;
    (void)user_data;
}


int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request (window, WINDOW_WIDTH, WINDOW_HEIGHT);
    gtk_widget_add_events (window, GDK_FOCUS_CHANGE_MASK);
                   
    g_signal_connect (G_OBJECT (window), "delete-event",
                      G_CALLBACK(delete_event), NULL);
    focus_in_id = g_signal_connect (G_OBJECT (window), "focus-in-event",
                      G_CALLBACK (focus_in_event), NULL);
    focus_out_id = g_signal_connect (G_OBJECT (window), "focus-out-event",
                      G_CALLBACK (focus_out_event), NULL);

    gtk_widget_show_all(window);

    gtk_main();

    return EXIT_SUCCESS;
}

Le Makefile correspondant :

CC=gcc
CFLAGS= -Wall -W -Werror -O2
CFLAGS += `pkg-config gtk+-3.0 --cflags`
LIB=`pkg-config gtk+-3.0 --libs`
EXE_NAME=focus

%.o: %.c
    $(CC) -c $(CFLAGS) -o $@ $<

$(EXE_NAME): $(EXE_NAME).o
    $(CC) -o $(EXE_NAME) $(EXE_NAME).o $(LIB)

Dernière modification par Tangram (Le 27/06/2012, à 22:54)

#2 Le 01/07/2012, à 09:10

Tangram

Re : C + GTK3 : Èvénements focus perdus pour les grandes fenêtres

Il n'y a que chez moi que le phénomène se produit ?

Peut-être me suis-je mal exprimé, donc je reprends :

1. Je lance le programme depuis un Terminal, ma petite fenêtre s'affiche.
2. Je clique sur le bouton (-) de la barre de fenêtre pour la faire disparaître, sur son icône pour la faire réapparaître, je fais passer la fenêtre derrière une autre fenêtre puis la fais repasser devant, je déplace la fenêtre. Les événements focus sont bien repérés. Pas de problème.
3. J'agrandis la fenêtre en la tirant par son coin en bas à droite, jusqu'à une taille relativement grande (chez moi, dans les 700x500).
4. Je répète les opérations du paragraphe 2 (plusieurs fois si nécessaire). Et au bout de quelques manips, les événements focus ne sont plus repérés, la sortie Terminal reste muette. On peut pourtant remarquer, en sortant du programme, que les signaux sont toujours connectés et que le GDK_FOCUS_CHANGE est toujours actif.

Alors, c'est grave, docteur ?

PS: le programme de test du message précédent doit être sauvé sous le nom 'focus.c'.

#3 Le 01/07/2012, à 23:43

xapantu

Re : C + GTK3 : Èvénements focus perdus pour les grandes fenêtres

Ben sur mon ordinateur, avec gnome shell, ça fonctionne correctement en tout cas. Essaye à tout hasard d'ajouter un widget qui peut prendre le focus à l'intérieur, dans la doc de gtk, ils parlent de keyboard focus, si tu n'as vraiment rien à l'intérieur, il pourrait être possible qu'il ne donne pas complètement le focus (bon, ça serait assez étonnant, mais je n'ai pas tellement d'autre idée). Et si tu utilise unity, essaye un autre wm peut être, comme mutter, ça pourrait aussi être un bug de compiz (qui, à un moment, avait fait des choses bizarres aux fenêtre minimisées) :

mutter --replace # ça va te virer une partie de l'interface, tu peux utiliser alt+tab et compagnie
# quand tu as finit de tester
unity --replace

Hors ligne

#4 Le 02/07/2012, à 11:01

Tangram

Re : C + GTK3 : Èvénements focus perdus pour les grandes fenêtres

Le mutter fait disparaître et réapparaître tout le bureau, mais fait que l'ordi tourne très très lentement.
J'ai fait une capture du Terminal :

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 2

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 3

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 4

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 5

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 6

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 7

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 8

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 9

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 10

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 11

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 12

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 13

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 14

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 15

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 16

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 17

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 18

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 19

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 20

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 21

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 22

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 23

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 24

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 25

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 26

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 27

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 28

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 29

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 30

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 31

(mutter:2103): Clutter-WARNING **: No listener with the specified listener id 32
Avertissement du gestionnaire de fenêtres : Log level 8: g_hash_table_remove_internal: assertion `hash_table != NULL' failed

(mutter:2103): Clutter-WARNING **: Not able to remove listener with id 1
Avertissement du gestionnaire de fenêtres : Log level 8: g_hash_table_size: assertion `hash_table != NULL' failed
Avertissement du gestionnaire de fenêtres : Received a NET_CURRENT_DESKTOP message from a broken (outdated) client who sent a 0 timestamp
Avertissement du gestionnaire de fenêtres : Buggy client sent a _NET_ACTIVE_WINDOW message with a timestamp of 0 for 0x3a000ac (defusr@def)
Avertissement du gestionnaire de fenêtres : meta_window_activate called by a pager with a 0 timestamp; the pager needs to be fixed.
Avertissement du gestionnaire de fenêtres : last_user_time (786325) is greater than comparison timestamp (784378).  This most likely represents a buggy client sending inaccurate timestamps in messages such as _NET_ACTIVE_WINDOW.  Trying to work around...
Avertissement du gestionnaire de fenêtres : 0x3a000ac (defusr@def) appears to be one of the offending windows with a timestamp of 786325.  Working around...
Avertissement du gestionnaire de fenêtres : Log level 8: meta_window_raise: assertion `!window->override_redirect' failed
Avertissement du gestionnaire de fenêtres : Buggy client sent a _NET_ACTIVE_WINDOW message with a timestamp of 0 for 0x1600002 (unity-2d-s)
Avertissement du gestionnaire de fenêtres : meta_window_activate called by a pager with a 0 timestamp; the pager needs to be fixed.

Il se peut que mon ordi commence aussi à fatiguer....