#!/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); }