Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplementation for Maurizio's gnome-screenshot hack #667

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 43 additions & 12 deletions bin/shutter
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ if ($goocanvas) {

#screenshot classes
require Shutter::Screenshot::SelectorAdvanced;
require Shutter::Screenshot::SelectorGnomeWayland;
require Shutter::Screenshot::SelectorSlurpWayland;
require Shutter::Screenshot::SelectorAuto;
require Shutter::Screenshot::Wayland;
require Shutter::Screenshot::Workspace;
Expand Down Expand Up @@ -466,8 +468,18 @@ sub STARTUP {
#UPDATE WINDOW LIST (signal is connected when GUI is loaded)

my $x11_supported = 1;
my $gnome_screenshot = 0;
my $slurp = 0;

if ($ENV{XDG_SESSION_TYPE} eq "wayland") {
$x11_supported = 0;
if (index(lc($ENV{XDG_CURRENT_DESKTOP}),"gnome") != -1 && -e "/usr/bin/gnome-screenshot") {
$gnome_screenshot = 1;
print "\n\n\n GNOME SCREENSHOT UNDER GNOME FOUND\n\n\n"; #DEBUG
} elsif (index(lc($ENV{XDG_CURRENT_DESKTOP}),"gnome") == -1 && -e "/usr/bin/slurp") {
$slurp = 1;
print "\n\n\n SLURP UNDER NON-GNOME FOUND\n\n\n"; #DEBUG
}
}

my $wnck_screen;
Expand Down Expand Up @@ -535,7 +547,7 @@ sub STARTUP {
$sm->{_menuitem_iclipboard}->signal_connect('activate', \&fct_clipboard_import);

unless ($x11_supported) {
for my $name ('selection', 'awindow', 'window', 'menu', 'tooltip') {
for my $name ('awindow', 'window', 'menu', 'tooltip') {
$sm->{"_menuitem_$name"}->set_sensitive(FALSE);
}
}
Expand Down Expand Up @@ -874,7 +886,7 @@ sub STARTUP {

unless ($x11_supported) {
my $tooltip = $d->get("Can't take screenshots without X11 server");
for my $name ('_select', '_window', '_menu', '_tooltip') {
for my $name ('_window', '_menu', '_tooltip') {
$st->{$name}->set_sensitive(FALSE);
$st->{$name}->set_tooltip_text($tooltip);
}
Expand Down Expand Up @@ -2980,7 +2992,7 @@ sub STARTUP {
#unblock signal handler
fct_control_signals('unblock');
return TRUE;
} elsif (!$x11_supported && $data ne "full" && $data ne "tray_full") {
} elsif (!$x11_supported && $data ne "full" && $data ne "tray_full" && $data ne "select" && $data ne "tray_select") {
my $sd = Shutter::App::SimpleDialogs->new;
$sd->dlg_error_message($d->get("Can't take screenshots without X11 server"), $d->get("Failed"));
fct_control_signals('unblock');
Expand Down Expand Up @@ -4252,8 +4264,8 @@ sub STARTUP {
# if $x11_supported is false, we are on Wayland, and all these buttons are already disabled and should stay disabled

#menu
$sm->{_menuitem_selection}->set_sensitive($sensitive);
if ($x11_supported) {
$sm->{_menuitem_selection}->set_sensitive($sensitive);
$sm->{_menuitem_window}->set_sensitive($sensitive);
#$sm->{_menuitem_section}->set_sensitive($sensitive);
$sm->{_menuitem_menu}->set_sensitive($sensitive);
Expand All @@ -4264,8 +4276,8 @@ sub STARTUP {
$sm->{_menuitem_iclipboard}->set_sensitive($sensitive);

#toolbar
$st->{_select}->set_sensitive($sensitive);
if ($x11_supported) {
$st->{_select}->set_sensitive($sensitive);
$st->{_window}->set_sensitive($sensitive);
#$st->{_section}->set_sensitive($sensitive);
$st->{_menu}->set_sensitive($sensitive);
Expand Down Expand Up @@ -6097,13 +6109,33 @@ sub STARTUP {

} else {

$screenshooter = Shutter::Screenshot::SelectorAdvanced->new(
$sc, $include_cursor, $delay_value, $notify_timeout_active->get_active,
$zoom_active->get_active, $hide_time->get_value, $as_help_active->get_active, $asel_size3->get_value,
$asel_size4->get_value, $asel_size1->get_value, $asel_size2->get_value, $as_confirmation_necessary->get_active,
);
if ($gnome_screenshot) {

print "\n\n\n We will be using gnome-screenshot!\n\n\n"; #DEBUG

$screenshooter = Shutter::Screenshot::SelectorGnomeWayland->new(
$sc, $include_cursor, $delay_value,
$notify_timeout_active->get_active, $hide_time->get_value,
);

$screenshot = $screenshooter->select_advanced();
$screenshot = $screenshooter->select_gnome_wayland();

} elsif ($slurp) {

print "\n\n\n We will be using slurp!\n\n\n"; #DEBUG

$screenshot = Shutter::Screenshot::SelectorSlurpWayland::xdg_portal($screenshooter);

} else {

$screenshooter = Shutter::Screenshot::SelectorAdvanced->new(
$sc, $include_cursor, $delay_value, $notify_timeout_active->get_active,
$zoom_active->get_active, $hide_time->get_value, $as_help_active->get_active, $asel_size3->get_value,
$asel_size4->get_value, $asel_size1->get_value, $asel_size2->get_value, $as_confirmation_necessary->get_active,
);

$screenshot = $screenshooter->select_advanced();
}

}

Expand Down Expand Up @@ -8488,7 +8520,6 @@ sub STARTUP {

#selection
my $menuitem_select = Gtk3::ImageMenuItem->new_with_mnemonic($d->get('_Selection'));
$menuitem_select->set_sensitive($x11_supported);
eval {
my $ccursor_pb = Gtk3::Gdk::Cursor::new('left_ptr')->get_image->scale_simple($shf->icon_size('menu'), 'bilinear');
$menuitem_select->set_image(Gtk3::Image->new_from_pixbuf($ccursor_pb));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
###################################################
#
# Copyright (C) 2008-2013 Mario Kemper <[email protected]>
#
# This file is part of Shutter.
#
# Shutter is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Shutter is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Shutter; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
###################################################

#perl -x -S perltidy -l=0 -b "%f"

package Shutter::Screenshot::SelectorGnomeWayland;

#modules
#--------------------------------------
use utf8;
use strict;
use warnings;

use Shutter::Screenshot::Main;
use Shutter::Screenshot::History;
use File::Temp qw/ tempfile tempdir /;

use Data::Dumper;
our @ISA = qw(Shutter::Screenshot::Main);

#Glib
use Glib qw/TRUE FALSE/;

#--------------------------------------

sub new {
my $class = shift;

#call constructor of super class (shutter_common, include_cursor, delay, notify_timeout)
my $self = $class->SUPER::new(shift, shift, shift, shift);

$self->{_hide_time} = shift; #a short timeout to give the server a chance to redraw the area that was obscured

$self->{_dpi_scale} = Gtk3::Window->new('toplevel')->get('scale-factor');

bless $self, $class;
return $self;
}

sub select_gnome_wayland {
my $self = shift;

#return value
my $output = 5;

my $cmdcursor = undef;

if ($self->{_include_cursor}) {
$cmdcursor = "-p";
}
else {
$cmdcursor = "";
}

#A short timeout to give the server a chance to
#redraw the area
Glib::Timeout->add(
$self->{_hide_time},
sub {
Gtk3->main_quit;
return FALSE;
});
Gtk3->main();

my $fh = File::Temp->new();
my $tmpfilename = $fh->filename;

system("gnome-screenshot", "-a", "-f", $tmpfilename, "-d", $self->{_delay}, $cmdcursor);

my $image = Gtk3::Image->new();
$image->set_from_file($tmpfilename);
$output = $image->get_pixbuf();

my $d = $self->{_sc}->get_gettext;

return $output;
}


sub redo_capture {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't actually redo any capture, will it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, this is just a remainder from the SelectorAdvance.pm module which I took as a base. I have some ideas, how redo could be possible (make a full screen screenshot with gnome-screenshot, then choose the proper area, but this would require to somehow get the information, what the proper area is, as now gnome-screenshot is responsible for doing the selection) but nothing working yet.

my $self = shift;
my $output = 3;
if (defined $self->{_history}) {
($output) = $self->get_pixbuf_from_drawable($self->{_history}->get_last_capture);
}
return $output;
}

sub get_history {
my $self = shift;
return $self->{_history};
}

sub get_error_text {
my $self = shift;
return $self->{_error_text};
}

sub get_action_name {
my $self = shift;
return $self->{_action_name};
}

sub quit {
my $self = shift;

$self->ungrab_pointer_and_keyboard(FALSE, FALSE, TRUE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did it grab them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another unnecessary remainder.

$self->clean;
}

sub clean {
my $self = shift;

$self->{_selector}->signal_handler_disconnect($self->{_selector_handler});
$self->{_view}->signal_handler_disconnect($self->{_view_zoom_handler});
$self->{_view}->signal_handler_disconnect($self->{_view_button_handler});
$self->{_view}->signal_handler_disconnect($self->{_view_event_handler});
$self->{_select_window}->signal_handler_disconnect($self->{_key_handler});
$self->{_select_window}->destroy;
$self->{_zoom_window}->destroy;
$self->{_prop_window}->destroy;
}

1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use utf8;
use strict;
use warnings;
use Net::DBus;
use Net::DBus::Reactor;
use Class::Struct;
use Data::Dumper;

package Shutter::Screenshot::SelectorSlurpWayland;

sub xdg_portal {
my $screenshooter = shift;
my $reactor = Net::DBus::Reactor->main;
my $bus = Net::DBus->find;
my $me = $bus->get_unique_name;
$me =~ s/\./_/g;
$me =~ s/^://g;

my $pixbuf;
my $output;

eval {
my $portal_service = $bus->get_service('org.freedesktop.portal.Desktop');
my $portal = $portal_service->get_object('/org/freedesktop/portal/desktop', 'org.freedesktop.portal.Screenshot');

my $num;
my $cb = sub {
($num, $output) = @_;
$reactor->shutdown;
};

my $token = 'shutter' . rand;
$token =~ s/\.//g;
my $request = $portal_service->get_object("/org/freedesktop/portal/desktop/request/$me/$token", 'org.freedesktop.portal.Request');
my $conn = $request->connect_to_signal(Response => $cb);
my $request_path = $portal->Screenshot('', {handle_token=>$token});
if ($request->get_object_path ne $request_path) {
$request->disconnect_from_signal(Response => $conn);
$request = $portal_service->get_object($request_path, 'org.freedesktop.portal.Request');
$conn = $request->connect_to_signal(Response => $cb);
}
$reactor->run;
$request->disconnect_from_signal(Response => $conn);
if ($num != 0) {
$screenshooter->{_error_text} = "Response $num from XDG portal";
return 9;
}
my $giofile = Glib::IO::File::new_for_uri($output->{uri});
print "xdg portal: got file ".$giofile->get_path."\n";
$pixbuf = Gtk3::Gdk::Pixbuf->new_from_file($giofile->get_path);
my $slurpoutput = `slurp`;
my ($x, $y, $width, $height) = split /[,x ]/, $slurpoutput;
my $s = {
'y' => $y,
'width' => $width,
'height' => $height,
'x' => $x
};

$output = take_screenshot($s, $pixbuf);
$giofile->delete;
};
if ($@) {
$screenshooter->{_error_text} = $@;
return 9;
};

return $output;
}

sub take_screenshot {
#my $self = shift;
my $s = shift;
my $clean_pixbuf = shift;

#my $d = $self->{_sc}->get_gettext;

my $output;

#no delay? then we take a subsection of the pixbuf in memory
if ($s && $clean_pixbuf ) {

$output = $clean_pixbuf->new_subpixbuf($s->{x}, $s->{y}, $s->{width}, $s->{height});

print "DEBUG OUTPUT=" . $output . "\n";

#if there is a delay != 0 set, we have to wait and get a new pixbuf from the root window
} else {
$output = 0;
}

return $output;
}

1;
Loading