Newsgroup: it.comp.os.linux.development
Titolo: GTK, applicare timeout a evento mouse

Tra ieri ed oggi mi son spremuto le meningi per risolvere un
problemuccio apparentemente banale, ma di cui non riesco a trovare una
soluzione valida.
Situazione: all'interno di una applicazione GTK+, dover emettere un
segnale (nella fattispecie, quello di "button-release") dopo un timeut
fissato che inizia al verificarsi di un altro evento.
Soluzioni provate:
- ho aggiunto la callback associata all'evento di button-release
all'interno del mainloop con "g_timeout_add", ma 1) se non rimuovo
l'evento subito dopo dal loop, esso viene emesso ad intervalli
regolari, non smette mai 2) se lo rimuovo con g_source_remove, la
callback viene chiusa immediatamente dopo e non posso usarla come
dovrei.
- ho tentato di capire il funzionamento di
gdk_event_send_client_message, ma dubito di averne compreso l'utilizzo:
tutto va in segfault, ed ho provato in diversi modi...
Qualcuno ha idee migliori delle mie? O, se la soluzione sta nell'uso di
qualche funzione di GDK, qualche illuminazione in merito?
Grazie :-)

 fissato che inizia al verificarsi di un altro evento.
Prima Legge della Programmazione ad Eventi: Gli Eventi Non Si
Sintetizzano A Meno Che Tu Non Sappia Esattamente Quello Che Stai
Facendo.
[e si: le maiuscole sono obbligatorie quando si riporta la Prima
Legge[*]]
Vediamo se ho capito cosa vuoi fare: vuoi "bloccare" un
"button-release-event", subordinandolo ad un altra azione? Se si, stai
violando apertamente la metafora - gli eventi, soprattutto quelli
originati da un pezzo di ferro, *avvengono*; sta a te programmarci
intorno pre-condizioni e post-condizioni.
Ribadisco il consiglio: prova a spiegare cosa vuoi fare (non *come*) e
perche', e vediamo se si riesce a risolvere.
+++
[*] Per i piu` curiosi, la Seconda Legge dice che: Se Stai Sintetizzando
Un Evento Non Sai Esattamente Quello Che Stai Facendo.
Ciao,
 Emmanuele.


In breve:
- viene premuto il tasto sinistro del mouse
- passa un tot di tempo
- si apre il menu contestuale che e' associato come callback al
rilascio del tasto destro
Sufficientemente chiaro?
Grazie per le delucidazioni sulle due Leggi ;-P

 Grazie per le delucidazioni sulle due Leggi ;-P
Dovere. :-)
Ciao,
 Emmanuele.

 ATTENZIONE: Codice non testato. NON copiare e incollare.
Direi che non ci sono problemi. ;-)
Per inciso, ho appena scritto un piccolo test in Perl, e funziona come
dovrebbe.
#v+
use Glib qw/TRUE FALSE/;
use Gtk2 '-init';
sub create_data {
    my $widget = shift;
    # should print 'Gtk2::Button'
    printf "Widget: %s\n", ref ($widget);
    # create the popup menu here, and use the 'button' and 'timestamp'
    # values in the Gtk2::Menu::popup method.
    return FALSE;
}
my $w = Gtk2::Window->new('toplevel');
$w->signal_connect(destroy => sub { Gtk2->main_quit });
my $b = Gtk2::Button->new('click me!');
$b->signal_connect(clicked => sub { $w->destroy });
$b->{'timestamp'} = 0;
$b->signal_connect(button_press_event => sub {
	my ($widget, $event) = @_;
	if ($event->button == 3) {
	    $widget->{'timestamp'} = $event->time;
	    $widget->{'button'} = $event->button;
	    $widget->{'timeout_id'} = Glib::Timeout->add (1000, \&create_data, $widget);
	    # we handled the third button case
	    return TRUE;
	}
	return FALSE;
    });
$b->signal_connect(button_release_event => sub {
	my ($widget, $event) = @_;
	if (($event->button == 3) &&
	    ($widget->{'timestamp'} > 0) &&
	    ($event->time - $widget->{'timestamp'} < 1000)) {
	    Glib::Source->remove ($widget->{'timeout_id'});
 
	    # reset data
	    $widget->{'timeout_id'} = 0;
	    $widget->{'timestamp'} = 0;
 
	    # we handled the third button case
	    return TRUE;
	}
	return FALSE;
    });
$w->add ($b);
$w->show_all;
Gtk2->main;
0;
#v-
Se tengo premuto il tasto destro per piu` di un secondo, il testo in
console appare, altrimenti nulla. La traduzione in C, o in linguaggi
minori come Python o Ruby, la lascio come esercizio per il lettore.
Ciao,
 Emmanuele.


E' esattamente la prima cosa che ho fatto (e riportata nel primo
messaggio di questo thread), ma precedentemente scartata in quanto
avevo notato che rilasciando il tasto il menu veniva chiuso.
Li' per li' avevo pensato ad un problema dovuto alla rimozione
dell'evento dal mainloop con g_source_remove(), ma a ben guardare il
mio codice forse il tutto era dovuto da una condizione che non avevo
previsto :-P
Vabbe': grazie per l'aiuto :-)

 usa il touchscreen di un tablet ;-)
Uh-oh, allor meglio se vai a leggerti questo:
 
http://live.gnome.org/GtkStylusMode
Prima. C'e` il caso che ci siano patch o codice in giro.
Ciao,
 Emmanuele.


Uh, non male il sitarello. In merito allo stylus mode non viene detto
molto (si menziona una fantomatica patch di cui non viene pero' dato il
link, cerchero' meglio...) ma gia' il solo fatto che qualcun'altro ci
stia lavorando mi conforta ;-).
E comunque, ci son un po' di risorse utili: passero' la serata a
visitarlo piu' approfonditamente ;-)
Grazie ancora :-)

 Grazie ancora :-)
Prego.
Ciao,
 Emmanuele.