Port techtalk-pse to use GTK3
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 9 Aug 2017 11:38:39 +0000 (12:38 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 9 Aug 2017 11:49:10 +0000 (12:49 +0100)
Should be functionally the same, with two caveats

It is not possible to use the screenshot fallback anymore since
Wayland doesn't permit taking screenshots via GDK APIs. You need
to call the compositor's DBus API. This is what 'gnome-screenshot'
already does, so just always rely on that existing.

For unknown reasons, the 'move' request is never honoured on the
top level window when in non-fullscreen mode.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
configure.ac
techtalk-pse.pl

index 56a2980..e82a1bd 100644 (file)
@@ -30,7 +30,7 @@ test "x$POD2TEXT" = "xno" &&
 
 dnl Check for required Perl modules.
 missing_perl_modules=no
 
 dnl Check for required Perl modules.
 missing_perl_modules=no
-for pm in Pod::Usage Getopt::Long Glib Gtk2 Gtk2::Gdk::Keysyms Gtk2::WebKit Gnome2::Vte; do
+for pm in Pod::Usage Getopt::Long Glib Gtk3 Glib::Object::Introspection; do
     AC_MSG_CHECKING([for $pm])
     if ! perl -M$pm -e1 >/dev/null 2>&1; then
         AC_MSG_RESULT([no])
     AC_MSG_CHECKING([for $pm])
     if ! perl -M$pm -e1 >/dev/null 2>&1; then
         AC_MSG_RESULT([no])
@@ -43,6 +43,15 @@ if test "x$missing_perl_modules" = "xyes"; then
     AC_MSG_FAILURE([some Perl modules required to run the program are missing])
 fi
 
     AC_MSG_FAILURE([some Perl modules required to run the program are missing])
 fi
 
+AC_MSG_CHECKING([for Vte 2.91])
+perl -e 'use Glib::Object::Introspection; Glib::Object::Introspection->setup(basename => "Vte", version => "2.91", package => "Vte");'
+if test $? == 0; then
+    AC_MSG_RESULT([yes])
+else
+    AC_MSG_RESULT([no])
+    AC_MSG_FAILURE(["Vte 2.91 required"])
+fi
+
 AC_CONFIG_FILES([techtalk-pse:techtalk-pse.pl],
                 [chmod 0555 techtalk-pse])
 AC_CONFIG_FILES([Makefile])
 AC_CONFIG_FILES([techtalk-pse:techtalk-pse.pl],
                 [chmod 0555 techtalk-pse])
 AC_CONFIG_FILES([Makefile])
index 71a4ee2..b495911 100755 (executable)
@@ -28,10 +28,11 @@ use Pod::Usage;
 use Getopt::Long;
 use Cwd qw(getcwd abs_path);
 use Glib qw(TRUE FALSE);
 use Getopt::Long;
 use Cwd qw(getcwd abs_path);
 use Glib qw(TRUE FALSE);
-use Gtk2 -init;
-use Gtk2::Gdk::Keysyms;
-use Gtk2::WebKit;
-use Gnome2::Vte;
+use Glib::Object::Introspection;
+use Gtk3 -init;
+use Gtk3::WebKit;
+
+Glib::Object::Introspection->setup(basename => "Vte", version => "2.91", package => "Vte");
 
 =encoding utf8
 
 
 =encoding utf8
 
@@ -199,6 +200,9 @@ my %files;
 my $current;
 my $pid;
 my $pipeline;
 my $current;
 my $pid;
 my $pipeline;
+my $fullscreen = 1;
+my $width;
+my $height;
 
 &reread_directory ();
 
 
 &reread_directory ();
 
@@ -207,15 +211,15 @@ if (@files == 0) {
     warn "techtalk-pse: no files found, continuing anyway ...\n"
 }
 
     warn "techtalk-pse: no files found, continuing anyway ...\n"
 }
 
-my $w = Gtk2::Window->new ();
-my $vbox = Gtk2::VBox->new ();
-my $webkit = Gtk2::WebKit::WebView->new ();
-my $vte = Gnome2::Vte::Terminal->new ();
-my $notebook = Gtk2::Notebook->new ();
+my $w = Gtk3::Window->new ("toplevel");
+my $vbox = Gtk3::VBox->new ();
+my $webkit = Gtk3::WebKit::WebView->new ();
+my $vte = Vte::Terminal->new ();
+my $notebook = Gtk3::Notebook->new ();
 my $splash = make_splash_page ();
 my $splash = make_splash_page ();
-my $emptylabel = Gtk2::Label->new ();
+my $emptylabel = Gtk3::Label->new ();
 
 
-my $webkitscroll = Gtk2::ScrolledWindow->new ();
+my $webkitscroll = Gtk3::ScrolledWindow->new();
 $webkitscroll->add ($webkit);
 $webkitscroll->set_policy('automatic', 'automatic');
 
 $webkitscroll->add ($webkit);
 $webkitscroll->set_policy('automatic', 'automatic');
 
@@ -241,8 +245,7 @@ $notebook->set_show_border(0);
 # NB careful setting it too big, because it will
 # force a min size on the terminal. Scaling 1.3
 # is biggest we can do while fitting 1024x768
 # NB careful setting it too big, because it will
 # force a min size on the terminal. Scaling 1.3
 # is biggest we can do while fitting 1024x768
-my $font = $vte->get_font;
-$font->set_size($font->get_size * 1.3);
+$vte->set_font_scale(1.3);
 
 # When an external command exits, automatically
 # go to the next slide
 
 # When an external command exits, automatically
 # go to the next slide
@@ -257,10 +260,20 @@ $vte->signal_connect (
 # Exit if the window is closed
 $w->signal_connect (
     destroy => sub {
 # Exit if the window is closed
 $w->signal_connect (
     destroy => sub {
-       Gtk2->main_quit;
+       Gtk3::main_quit;
        return FALSE;
     });
 
        return FALSE;
     });
 
+$w->signal_connect (
+    'window-state-event' => sub {
+       if (!$fullscreen) {
+           $w->resize ($width, $height);
+           $w->move (500, 500);
+       }
+        return FALSE;
+    });
+
+
 # Handle left/right arrows, page up/down & home/end
 # as slide navigation commands. But not when there
 # is a shell running
 # Handle left/right arrows, page up/down & home/end
 # as slide navigation commands. But not when there
 # is a shell running
@@ -274,23 +287,23 @@ $w->signal_connect (
            return 0;
        }
 
            return 0;
        }
 
-       if ($ev->keyval == $Gtk2::Gdk::Keysyms{Right} ||
-           $ev->keyval == $Gtk2::Gdk::Keysyms{Page_Down}) {
+       if ($ev->keyval == &Gtk3::Gdk::KEY_Right ||
+           $ev->keyval == &Gtk3::Gdk::KEY_Page_Down) {
            &switch_slide("NEXT");
            return 1;
            &switch_slide("NEXT");
            return 1;
-       } elsif ($ev->keyval == $Gtk2::Gdk::Keysyms{Left} ||
-                $ev->keyval == $Gtk2::Gdk::Keysyms{Page_Up}) {
+       } elsif ($ev->keyval == &Gtk3::Gdk::KEY_Left ||
+                $ev->keyval == &Gtk3::Gdk::KEY_Page_Up) {
            &switch_slide("PREV");
            return 1;
            &switch_slide("PREV");
            return 1;
-       } elsif ($ev->keyval == $Gtk2::Gdk::Keysyms{Home}) {
+       } elsif ($ev->keyval == &Gtk3::Gdk::KEY_Home) {
            &switch_slide("FIRST");
            return 1;
            &switch_slide("FIRST");
            return 1;
-       } elsif ($ev->keyval == $Gtk2::Gdk::Keysyms{End}) {
+       } elsif ($ev->keyval == &Gtk3::Gdk::KEY_End) {
            &switch_slide("LAST");
            return 1;
            &switch_slide("LAST");
            return 1;
-       } elsif ($ev->keyval == $Gtk2::Gdk::Keysyms{q} ||
-                $ev->keyval == $Gtk2::Gdk::Keysyms{Escape}) {
-           Gtk2->main_quit;
+       } elsif ($ev->keyval == &Gtk3::Gdk::KEY_q ||
+                $ev->keyval == &Gtk3::Gdk::KEY_Escape) {
+           Gtk3::main_quit;
            return 1;
        }
        return 0;
            return 1;
        }
        return 0;
@@ -299,16 +312,12 @@ $w->signal_connect (
 
 $w->add ($vbox);
 
 
 $w->add ($vbox);
 
-# This allows us to resize the window in window_in_corner().
-$w->set_geometry_hints ($w, { min_width => 100 }, qw(min-size));
-
 $w->show_all ();
 $w->show_all ();
-
 window_fullscreen ();
 
 &update_slide();
 
 window_fullscreen ();
 
 &update_slide();
 
-Gtk2->main();
+Gtk3::main();
 
 exit 0;
 
 
 exit 0;
 
@@ -362,24 +371,27 @@ sub window_fullscreen
 {
     $w->set_decorated (0);
     $w->fullscreen ();
 {
     $w->set_decorated (0);
     $w->fullscreen ();
-    $w->move (0,0);
+    $fullscreen = 1;
 }
 
 sub window_in_corner
 {
     $w->set_decorated (1);
     $w->unfullscreen ();
 }
 
 sub window_in_corner
 {
     $w->set_decorated (1);
     $w->unfullscreen ();
+    $fullscreen = 0;
 
 
-    my $root = Gtk2::Gdk->get_default_root_window ();
-    my ($width, $height) = $root->get_size;
+    my $gwin = $w->get_window();
+    my $monitor = $w->get_display()->get_monitor_at_window($gwin);
+    my $geom = $monitor->get_geometry();
 
 
-    $w->resize ($width/2, $height/4);
-    $w->move ($width/2, 64);
+    $width = $geom->{width} / 2;
+    $height = $geom->{height} / 4;
 }
 
 sub run_process
 {
 }
 
 sub run_process
 {
-    $pid = $vte->fork_command("./" . $current->{name}, [], [], undef, 0, 0, 0);
+    my @ret = $vte->spawn_sync('default', ".", ["./" . $current->{name}], [], 'default');
+    $pid = $ret[1];
 }
 
 sub kill_process
 }
 
 sub kill_process
@@ -493,28 +505,28 @@ sub update_slide
 
 
 sub make_splash_page {
 
 
 sub make_splash_page {
-    my $box = Gtk2::VBox->new();
+    my $box = Gtk3::VBox->new();
 
 
-    my $title = Gtk2::Label->new ("<b><span size='x-large'>Tech Talk Platinum Supreme Edition (PSE)</span></b>");
+    my $title = Gtk3::Label->new ("<b><span size='x-large'>Tech Talk Platinum Supreme Edition (PSE)</span></b>");
     $title->set_use_markup (1);
 
     $box->pack_start ($title, 0, 1, 0);
 
     $title->set_use_markup (1);
 
     $box->pack_start ($title, 0, 1, 0);
 
-    my $vers = Gtk2::Label->new ("<b><span size='large'>@VERSION@</span></b>");
+    my $vers = Gtk3::Label->new ("<b><span size='large'>@VERSION@</span></b>");
     $vers->set_use_markup (1);
     $box->pack_start ($vers, 0, 1, 0);
 
     $vers->set_use_markup (1);
     $box->pack_start ($vers, 0, 1, 0);
 
-    my $tagline = Gtk2::Label->new ("<i><span size='large'>Superior technical demonstration software</span></i>");
+    my $tagline = Gtk3::Label->new ("<i><span size='large'>Superior technical demonstration software</span></i>");
     $tagline->set_use_markup (1);
 
     $box->pack_start ($tagline, 0, 1, 0);
     $tagline->set_use_markup (1);
 
     $box->pack_start ($tagline, 0, 1, 0);
-    $box->pack_start (Gtk2::Label->new (""), 0, 1, 0);
-    $box->pack_start (Gtk2::Label->new ("Author: Richard W.M. Jones"), 0, 1, 0);
+    $box->pack_start (Gtk3::Label->new (""), 0, 1, 0);
+    $box->pack_start (Gtk3::Label->new ("Author: Richard W.M. Jones"), 0, 1, 0);
 
 
-    my $url = Gtk2::Label->new ("<a href='http://people.redhat.com/~rjones'>http;//people.redhat.com/~rjones/</a>");
+    my $url = Gtk3::Label->new ("<a href='http://people.redhat.com/~rjones'>http://people.redhat.com/~rjones/</a>");
     $url->set_use_markup (1);
     $box->pack_start ($url, 0, 1, 0);
     $url->set_use_markup (1);
     $box->pack_start ($url, 0, 1, 0);
-    $box->pack_start (Gtk2::Label->new ("GNU General Public License v2 or above"), 0, 1, 0);
+    $box->pack_start (Gtk3::Label->new ("GNU General Public License v2 or above"), 0, 1, 0);
 
     return $box;
 }
 
     return $box;
 }
@@ -522,30 +534,30 @@ sub make_splash_page {
 # Make the standard button bar across the top of the page.
 sub make_button_bar
 {
 # Make the standard button bar across the top of the page.
 sub make_button_bar
 {
-    my $bbox = Gtk2::Toolbar->new ();
+    my $bbox = Gtk3::Toolbar->new ();
     $bbox->set_style ("GTK_TOOLBAR_TEXT");
 
     my $i = 0;
 
     $bbox->set_style ("GTK_TOOLBAR_TEXT");
 
     my $i = 0;
 
-    my $bquit = Gtk2::ToolButton->new (undef, "Quit");
-    $bquit->signal_connect (clicked => sub { Gtk2->main_quit });
+    my $bquit = Gtk3::ToolButton->new (undef, "Quit");
+    $bquit->signal_connect (clicked => sub { Gtk3::main_quit });
     $bbox->insert ($bquit, $i++);
 
     $bbox->insert ($bquit, $i++);
 
-    my $breload = Gtk2::ToolButton->new (undef, "Reload");
+    my $breload = Gtk3::ToolButton->new (undef, "Reload");
     $breload->signal_connect (clicked => sub { reread_directory () });
     $bbox->insert ($breload, $i++);
 
     $breload->signal_connect (clicked => sub { reread_directory () });
     $bbox->insert ($breload, $i++);
 
-    my $bnext = Gtk2::ToolButton->new (undef, "Next slide");
+    my $bnext = Gtk3::ToolButton->new (undef, "Next slide");
     $bnext->signal_connect (clicked => sub { &switch_slide ("NEXT") });
     $bbox->insert ($bnext, $i++);
 
     $bnext->signal_connect (clicked => sub { &switch_slide ("NEXT") });
     $bbox->insert ($bnext, $i++);
 
-    my $bback = Gtk2::ToolButton->new (undef, "Back");
+    my $bback = Gtk3::ToolButton->new (undef, "Back");
     $bback->signal_connect (clicked => sub { &switch_slide ("PREV") });
     $bbox->insert ($bback, $i++);
 
     $bback->signal_connect (clicked => sub { &switch_slide ("PREV") });
     $bbox->insert ($bback, $i++);
 
-    $bbox->insert (Gtk2::SeparatorToolItem->new (), $i++);
+    $bbox->insert (Gtk3::SeparatorToolItem->new (), $i++);
 
 
-    my $brestart = Gtk2::ToolButton->new (undef, "Kill & restart");
+    my $brestart = Gtk3::ToolButton->new (undef, "Kill & restart");
     $brestart->signal_connect (clicked =>
                               sub {
                                   kill_process ();
     $brestart->signal_connect (clicked =>
                               sub {
                                   kill_process ();
@@ -553,26 +565,26 @@ sub make_button_bar
                               });
     $bbox->insert ($brestart, $i++);
 
                               });
     $bbox->insert ($brestart, $i++);
 
-    my $sep = Gtk2::SeparatorToolItem->new ();
+    my $sep = Gtk3::SeparatorToolItem->new ();
     $sep->set_expand (TRUE);
     $sep->set_draw (FALSE);
     $bbox->insert ($sep, $i++);
 
     $sep->set_expand (TRUE);
     $sep->set_draw (FALSE);
     $bbox->insert ($sep, $i++);
 
-    my $optsmenu = Gtk2::Menu->new ();
+    my $optsmenu = Gtk3::Menu->new ();
 
 
-    my $mfirst = Gtk2::MenuItem->new ("First slide");
+    my $mfirst = Gtk3::MenuItem->new ("First slide");
     $mfirst->signal_connect (activate => sub { &switch_slide ("FIRST") });
     $mfirst->show ();
     $optsmenu->append ($mfirst);
 
     $mfirst->signal_connect (activate => sub { &switch_slide ("FIRST") });
     $mfirst->show ();
     $optsmenu->append ($mfirst);
 
-    my $mlast = Gtk2::MenuItem->new ("Last slide");
+    my $mlast = Gtk3::MenuItem->new ("Last slide");
     $mlast->signal_connect (activate => sub { &switch_slide ("LAST") });
     $mlast->show ();
     $optsmenu->append ($mlast);
 
     $mlast->signal_connect (activate => sub { &switch_slide ("LAST") });
     $mlast->show ();
     $optsmenu->append ($mlast);
 
-    my $slidesmenu = Gtk2::Menu->new ();
+    my $slidesmenu = Gtk3::Menu->new ();
     foreach (@files) {
     foreach (@files) {
-        my $item = Gtk2::MenuItem->new ($_->{name});
+        my $item = Gtk3::MenuItem->new ($_->{name});
         my $index = $_->{i};
         $item->signal_connect (activate => sub { &switch_slide ("I_$index") });
         $item->set_sensitive ($current->{i} != $index);
         my $index = $_->{i};
         $item->signal_connect (activate => sub { &switch_slide ("I_$index") });
         $item->set_sensitive ($current->{i} != $index);
@@ -580,30 +592,30 @@ sub make_button_bar
         $slidesmenu->append ($item);
     }
 
         $slidesmenu->append ($item);
     }
 
-    my $mslides = Gtk2::MenuItem->new ("Slides");
+    my $mslides = Gtk3::MenuItem->new ("Slides");
     $mslides->set_submenu ($slidesmenu);
     $mslides->show ();
     $optsmenu->append ($mslides);
 
     $mslides->set_submenu ($slidesmenu);
     $mslides->show ();
     $optsmenu->append ($mslides);
 
-    my $sep2 = Gtk2::SeparatorMenuItem->new ();
+    my $sep2 = Gtk3::SeparatorMenuItem->new ();
     $sep2->show ();
     $optsmenu->append ($sep2);
 
     $sep2->show ();
     $optsmenu->append ($sep2);
 
-    my $mscreenshot = Gtk2::MenuItem->new ("Take a screenshot");
+    my $mscreenshot = Gtk3::MenuItem->new ("Take a screenshot");
     $mscreenshot->signal_connect (activate => sub { screenshot () });
     $mscreenshot->show ();
     $optsmenu->append ($mscreenshot);
 
     $mscreenshot->signal_connect (activate => sub { screenshot () });
     $mscreenshot->show ();
     $optsmenu->append ($mscreenshot);
 
-    my $sep3 = Gtk2::SeparatorMenuItem->new ();
+    my $sep3 = Gtk3::SeparatorMenuItem->new ();
     $sep3->show ();
     $optsmenu->append ($sep3);
 
     $sep3->show ();
     $optsmenu->append ($sep3);
 
-    my $mquit = Gtk2::MenuItem->new ("Quit");
-    $mquit->signal_connect (activate => sub { Gtk2->main_quit });
+    my $mquit = Gtk3::MenuItem->new ("Quit");
+    $mquit->signal_connect (activate => sub { Gtk3::main_quit });
     $mquit->show ();
     $optsmenu->append ($mquit);
 
     $mquit->show ();
     $optsmenu->append ($mquit);
 
-    my $moptions = Gtk2::MenuToolButton->new (undef, "Options");
+    my $moptions = Gtk3::MenuToolButton->new (undef, "Options");
     #$boptions->signal_connect (clicked =>
     #  sub { $optsmenu->popup (undef, undef, undef, undef, ?, ?) } );
     $bbox->insert ($moptions, $i++);
     #$boptions->signal_connect (clicked =>
     #  sub { $optsmenu->popup (undef, undef, undef, undef, ?, ?) } );
     $bbox->insert ($moptions, $i++);
@@ -612,29 +624,11 @@ sub make_button_bar
     return ($bbox, $bquit, $breload, $bnext, $bback, $brestart);
 }
 
     return ($bbox, $bquit, $breload, $bnext, $bback, $brestart);
 }
 
-# Try running the external "gnome-screenshot" program, if it's
-# available, else take a screenshot using gdk routines.
+# Try running the external "gnome-screenshot" program
 sub screenshot
 {
     system ("gnome-screenshot");
 
 sub screenshot
 {
     system ("gnome-screenshot");
 
-    if ($? == -1) {
-        # We are going to save the entire screen.
-        my $root = Gtk2::Gdk->get_default_root_window ();
-        my ($width, $height) = $root->get_size;
-
-        # Create blank pixbuf to hold the image.
-        my $gdkpixbuf = Gtk2::Gdk::Pixbuf->new ('rgb',
-                                                0, 8, $width, $height);
-
-        $gdkpixbuf->get_from_drawable ($root, $root->get_colormap (),
-                                       0, 0, 0, 0, $width, $height);
-
-        my $i = 0;
-        $i++ while -f "screenshot$i.png";
-        $gdkpixbuf->save ("screenshot$i.png", 'png');
-    }
-
     return FALSE;
 }
 
     return FALSE;
 }