Как проверить наличие CTRL + s в Gtk3? - PullRequest
0 голосов
/ 06 мая 2019

Как я могу проверить, нажата ли клавиша вместе с определенным модификатором в Gtk3 ? Например, здесь я хочу проверить, нажата ли CTRL + s :

use feature qw(say);
use strict;
use warnings;
use Gtk3 '-init';
use Glib qw(TRUE FALSE);

my $window = Gtk3::Window->new('toplevel');
$window->set_title('Hello world');
$window->set_position('center');
$window->set_default_size(500, 500);
$window->signal_connect('delete-event' => sub {
    Gtk3->main_quit();
});
$window->signal_connect('key-press-event' => sub { handle_key( @_ ) } );
$window->show_all();
Gtk3->main();

sub handle_key {
    my ( $widget, $event) = @_;

    my $key = Gtk3::Gdk::keyval_name( $event->keyval );
    if ( ($key eq 's') && control_pressed( $event ) ) {
        say "CTRL+S";
    }
    return FALSE; # FALSE -> means propagate key further
}

Как мне определить функцию control_pressed() выше?

1 Ответ

0 голосов
/ 06 мая 2019

$event->state имеет тип Gtk3::Gdk::ModifierType, который имеет перегруженные операторы .

Флаги имеют некоторые дополнительные магические способности в виде перегруженных Операторы:

+ or |   union of two flagsets ("add")
-        difference of two flagsets ("sub", "remove")   
* or &   intersection of two bitsets ("and")   
/ or ^   symmetric difference ("xor", you will rarely need this)
>=       contains-operator ("is the left set a superset of the right set?")
==       equality

Кроме того, флаги в логическом контексте указать, являются ли они пустыми или нет, что позволяет писать обычные операции естественно:

$widget->set_events ($widget->get_events - "motion_notify_mask");  
$widget->set_events ($widget->get_events - ["motion_notify_mask",
                                          "button_press_mask"]);

# shift pressed (both work, it's a matter of taste)   
if ($event->state >= "shift-mask") { ...   
if ($event->state * "shift-mask") { ...

# either shift OR control pressed?   
if ($event->state * ["shift-mask", "control-mask"]) { ...

# both shift AND control pressed?
if ($event->state >= ["shift-mask", "control-mask"]) { ...

Кроме того, константы для перечисления GdkModifierType становятся строчными буквами в Perl. Поэтому должно работать следующее:

sub control_pressed {
    my ( $event ) = @_;

    return $event->state & 'control-mask';
}
...