Category: | Gui Programming |
Author/Contact Info | zentara of perlmonks |
Description: | Warning...contains some X windows trickery, and should not be run while important things are going on on your desktop. It will not destroy anything, just be annoying. This is some Gtk2 code that will find all non-maximized windows (on all virtual desktops), and start them jumping like crazy. A control window is placed in the center (immune to the jumping), which has a global keyboard grab, so you can kill the program. Use cautiously. :-) Developed for a school audio visual tech, who needed to pretend to be fixing malfunctioning monitors, all the while partying in the back room. :-) It does show an important concept, of doing a global keyboard grab with Gtk2. |
#!/usr/bin/perl use warnings; use strict; use Gtk2 -init; use Gnome2::Wnck; # section to get all windows my @gdk; my $s = Gtk2::Gdk::Screen->get_default; my $gdkwindow = $s->get_root_window; my ($x0, $y0, $width0, $height0, $depth) = $gdkwindow->get_geometry; #print "geometry x0->$x0, y0->$y0, width->$width0, height->$height0, d +epth->$depth\n"; my $screen = Gnome2::Wnck::Screen->get_default; $screen->force_update; my @windows = $screen->get_windows; foreach my $fwin (@windows) { push @gdk, Gtk2::Gdk::Window->foreign_new($fwin->get_xid); } ######################## ### control window section with a global grab ############ my $password= 'q'; my $message="Type $password then enter to quit"; my $typed=""; my $gdkwin; my $mw = new Gtk2::Window('popup'); $mw->set_position('center'); # see below for invisible window 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); # if you don't want someone to see password window, # just move it out of sight :-) # $mw->signal_connect('realize', sub { $mw->window->move(2000,2000); } +); # must define gdkwin after it is mapped $mw->signal_connect('map', sub { $gdkwin = $mw->window ; do_grab(); }) +; $mw->show_all; # make the jumping occur my $timer = Glib::Timeout->add (100, \&jump ); 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>"); } ##################################### sub jump{ foreach( @gdk){ # print "$_\n"; my $xd = rand $width0/2; my $yd = rand $height0/2; $_->move($xd,$yd) } Gtk2->main_iteration while Gtk2->events_pending; return 1; } |
|
---|