Just for the sake of gtk2 posterity, I will post the example codes I've cobbled together, mostly from the gtk2-perl maillist archives.
Anyways, on to the show as they say. Just run them and see the difference.
globalkeyboardgrab#0
#!/usr/bin/perl
use warnings;
use strict;
my $password= 'q';
my $message="Type password to quit\n:";
my $noshow='stars'; # 1,0,or stars
my $maxshownlength=30;
my @startpos=(100,100);
use Gtk2 -init;
my $w = new Gtk2::Window('popup');
my $l = new Gtk2::Label($message);
my $eb = new Gtk2::EventBox;
my $gdkwin;
my $grabstatus;
my $typed="";
$w->add($eb);
$eb->add($l);
$w->add_events( [ qw(key_press_mask) ]);
$w->signal_connect('key_press_event', \&do_keypress);
$w->signal_connect('realize', sub { $w->window->move(@startpos); });
$w->signal_connect('map', sub { $gdkwin=$w->window; do_grab(); });
$w->show_all;
Gtk2->main;
sub do_grab()
{
$grabstatus= Gtk2::Gdk->keyboard_grab(
$gdkwin, 1 ,Gtk2::Gdk::X11->get_server_time($gdkwin) );
if($grabstatus ne "success")
{
$l->set_text("keyboard grab failed");
}
}
sub do_ungrab()
{
Gtk2::Gdk->keyboard_ungrab(Gtk2::Gdk::X11->get_server_time($gdkwin))
+;
}
sub do_keypress(@)
{
my ($widg,$evt)=@_;
my $kv = $evt->keyval;
my $cs = Gtk2::Gdk->keyval_name($kv);
if($cs =~ /Return|Enter/){
if($typed eq $password) {
do_ungrab();
Gtk2->main_quit;
}else{
$typed="";
}
}elsif(length($cs) == 1 && $cs =~ /[[:print:]]/){
$typed .= $cs;
}
my $showtyped=$typed;
if($noshow eq "stars"){
$showtyped =~ s/[^*]/*/g;
} elsif($noshow){ $showtyped="";
}
if(length($showtyped) > $maxshownlength){
$showtyped=substr($showtyped,0,$maxshownlength);
}
$l->set_text($message.$showtyped);
}
globalkeyboardgrab#1
#!/usr/bin/perl
use warnings;
use strict;
use Gtk2 -init;
my $password= 'q';
my $message="Type password to quit";
my $typed="";
my $gdkwin;
my $mw = new Gtk2::Window('popup');
$mw->set_position('center');
my $vbox = Gtk2::VBox->new(0,5);
$mw->add($vbox);
my $msg_w_markup = Gtk2::Label->new();
$msg_w_markup->set_justify('left');
$msg_w_markup->set_markup("
<span background = 'black' foreground= 'green' size ='30000'> <i>$mess
+age</i></span>");
$vbox->pack_start($msg_w_markup,0,0,4);
my $typed_w_markup = Gtk2::Label->new();
$typed_w_markup->set_justify('left');
$typed_w_markup->set_alignment(0, 0.5);
$typed_w_markup->set_markup("
<span background = 'black' foreground= 'red' size ='30000'>$typed</spa
+n>");
$vbox->pack_start($typed_w_markup,0,0,4);
$mw->add_events( [ qw(key_press_mask) ]);
$mw->signal_connect('key_press_event', \&do_keypress);
#$mw->signal_connect('realize', sub { $mw->window->move(50,40); });
# must define gdkwin after it is mapped
$mw->signal_connect('map', sub { $gdkwin = $mw->window ; do_grab(); })
+;
$mw->show_all;
Gtk2->main;
sub do_grab()
{
my $grabstatus= Gtk2::Gdk->keyboard_grab(
$gdkwin, 1 ,Gtk2::Gdk::X11->get_server_time($gdkwin) );
if($grabstatus ne "success")
{
$msg_w_markup->set_text("keyboard grab failed");
}
}
sub do_ungrab()
{
Gtk2::Gdk->keyboard_ungrab(Gtk2::Gdk::X11->get_server_time($gdkwin))
+;
}
sub do_keypress(@)
{
my ($widget,$event)=@_;
my $kv = $event->keyval;
my $kn = Gtk2::Gdk->keyval_name($kv);
if($kn =~ /Return|Enter/){
if($typed eq $password) {
do_ungrab();
Gtk2->main_quit;
}else{
$typed="";
}
}elsif(length($kn) == 1 && $kn =~ /[[:print:]]/){
$typed .= $kn;
}
my $showtyped=$typed;
if(length($showtyped) > 30){
$showtyped=substr($showtyped,0,30);
}
$typed_w_markup->set_markup("
<span background = 'black' foreground= 'red' size ='30000'> <i>$sh
+owtyped</i></span>");
}
and finally window-centered-global-grab
#!/usr/bin/perl
use warnings;
use strict;
use Glib qw/TRUE FALSE/;
use Gtk2::Gdk::Keysyms;
use Gtk2 '-init';
$|++;
my $window = Gtk2::Window->new('toplevel');
$window->set_title('Z0');
$window ->signal_connect( 'destroy' => \&delete_event );
$window->set_border_width(10);
$window->set_size_request(300,200);
my $window1 = Gtk2::Window->new('toplevel');
$window1->set_title('Z1');
$window1->set_border_width(10);
$window1->set_size_request(300,200);
my $textbuffer1 = Gtk2::TextBuffer->new();
my $textview1 = Gtk2::TextView->new_with_buffer($textbuffer1);
$window1->add($textview1);
my $vbox = Gtk2::VBox->new( FALSE, 6 );
$window->add($vbox);
$vbox->set_border_width(2);
my $textbuffer = Gtk2::TextBuffer->new();
my $textview = Gtk2::TextView->new_with_buffer($textbuffer);
$vbox->pack_start($textview,1,1,0);
my $hbox= Gtk2::HBox->new( FALSE, 6 );
$vbox->pack_end($hbox,FALSE,FALSE,0);
$hbox->set_border_width(2);
my $button = Gtk2::Button->new_from_stock('gtk-quit');
$hbox->pack_end( $button, FALSE, FALSE, 0 );
$button->signal_connect( clicked => \&delete_event );
my $button1 = Gtk2::Button->new('Global Grab');
$hbox->pack_end( $button1, FALSE, FALSE, 0 );
$button1->signal_connect( clicked => sub{
# my $rc;
# $rc = Gtk2::Gdk->pointer_grab($window->window,1,['button-press-mask
+','button-release-mask','pointer-motion-mask'],undef,undef,Gtk2->get_
+current_event_time);
# print "$rc\n";
# $rc = Gtk2::Gdk->keyboard_grab($window->window,0,Gtk2->get_current_
+event_time);
# print "$rc\n";
$window->grab_focus;
} );
$window->set_position('center');
$window->show_all();
$window1->show_all();
$window->signal_connect( 'key_release_event' => \&keyrelease );
$window->signal_connect (event => sub {
my ($item, $event) = @_;
warn "event ".$event->type."\n";
# print chr(07); #beep
return 0; #return 1 prevents window from closing
# return 0 lets the signal thru
});
Gtk2->main;
#####################################
sub delete_event {
Gtk2->main_quit;
return FALSE;
}
sub keyrelease {
my ( $widget, $event ) = @_;
print $event->keyval,"\n";
print chr(07); #beep
if ( $event->keyval == $Gtk2::Gdk::Keysyms{q} ) {
Gtk2->main_quit;
}
else {
print "key was ", chr( $event->keyval ), "\n";
}
}
|