http://www.perlmonks.org?node_id=1003564


in reply to Gtk2-Perl: How to catch shift-clicking of a button?

There are few problems that you have to resolve. First of all. The "key-press-event" signal goes only to widgets that have focus and to the top-level window. Normal button does not have focus until it is clicked, or until you move focus to it using Tab. I would recommend to associate "key-press-event" handler not with button, but with some area that will definitely have focus when you press the Shift button.

Then comes the event handling. You need both key-press-event and key-release-event handlers. The first one would set some internal variable when it receives event notifying that the Shift was pressed. The second one would clear that variable when the Shift is released. The "clicked" event handler shall check that variable to see if it is set or not set. In the events for key you can even change the label of the button or do some other stuff.

Note. The "key-press-event" and "key-release-event" handlers should wait for event containing Shift_L or Shift_R as keyval. Here's the example program.

#!/usr/bin/perl use strict; use Gtk2 -init; use Gtk2::Gdk::Keysyms; my $win = Gtk2::Window->new('toplevel'); $win->signal_connect(destroy => sub { Gtk2->main_quit }); $win->signal_connect(key_press_event => \&report_press); $win->signal_connect(key_release_event => \&report_release); my $but = Gtk2::Button->new('No Shift'); $but->signal_connect(clicked => \&report_click); $win->add($but); $win->show_all; Gtk2->main; sub report_click { my $w = shift; print $w->get_label, "\n"; } sub report_press { my $w = shift; my $ev = shift; if($ev->keyval == $Gtk2::Gdk::Keysyms{Shift_L} || $ev->keyval == $Gtk2::Gdk::Keysyms{Shift_R}) { $but->set_label("With Shift"); } return; } sub report_release { my $w = shift; my $ev = shift; if($ev->keyval == $Gtk2::Gdk::Keysyms{Shift_L} || $ev->keyval == $Gtk2::Gdk::Keysyms{Shift_R}) { $but->set_label("No Shift"); } return; }