ClutterGestureAction

Clutter @ Mouse Drag | PaePoi
にてシークバーを motion-event で動かすようにした。

しかしこの方法は問題があった。
マウスカーソルが ClutterActor から外れるとシグナルが無効化される。
カーソルのキャプチャが必要だが手段が解らない。

いくら手段を探しても見つからない、もしかして無いのかも。
もう別のシーク方法を考えたほうが良さそうだ。

ClutterDragAction でなく ClutterGestureAction ならどうだ?
タッチパネル向けアクションだと思って無視していたけど調べてみよう。

ClutterGestureAction: Clutter Reference Manual

clutter_gesture_action_get_motion_coords
で普通に x, y の値が抜けるみたいだね。
問題はマウスカーソルが外れてもキャプチャするかどうかだ、実験。

#!/usr/bin/gjs

const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

const GestureTest = new Lang.Class({
    Name: 'GestureTest',
    Extends: Clutter.Stage,

    _init: function() {
        this.parent();
        // var
        this.is_drag = false;
        // text
        this.text = new Clutter.Text();
        this.text.set_text("x = NULL; y = NULL");
        this.add_child(this.text);
        // Action
        let gesture = new Clutter.GestureAction();
        gesture.connect("gesture-begin", Lang.bind(this, function(action, actor) {
            let x = action.get_press_coords(0)[0] / this.width;
            let y = action.get_press_coords(0)[1] / this.height;
            this.text.set_text("x = " + x + "; y = " + y);
            return true;
        }));
        gesture.connect("gesture-progress", Lang.bind(this, function(action, actor) {
            let x = action.get_motion_coords(0)[0] / this.width;
            let y = action.get_motion_coords(0)[1] / this.height;
            this.text.set_text("x = " + x + "; y = " + y);
            return true;
        }));
        gesture.connect("gesture-end", Lang.bind(this, function(action, actor) {
            this.text.set_text("x = NULL; y = NULL");
        }));
        this.add_action(gesture);
        this.set_reactive(true);
        // this
        this.connect("hide", Clutter.main_quit);
        this.show_all();
    }
});

Clutter.init(null);
new GestureTest();
Clutter.main();

にてマウスをウインドウの外まで移動

clutter_gesture_action

しっかりマイナス値も取得できていますね。
ウインドウ外でマウスボタンを離すとしっかり NULL に戻る。

なんだよ、こんなに簡単な手段があったじゃないか。
昔の手段で思考停止していたら駄目だね、どんどん新しいことをやらないと。
ついでに。

this.player = new ClutterGst.Playback();
this.player.set_seek_flags(ClutterGst.SeekFlags.ACCURATE);

これだけでシークバーの追従がナイスになる。
思い通りに動かなかったものがキチンと動くようになっていくのはマジ楽しい。