フルスクリーン時にマウスカーソルを上に持って行くとヘッダーがヒョッコリ。
という処理は GTK+ なら GtkOverlay で簡単に実現できる。
けれど Y901x でやってみたらどうやっても表示してくれない。
GtkOverlay は GtkClutter.Embed の上には被せることができないようだ。
なので GtkClutter.Actor の上にヘッダーを置いて表示させるしかない。
GTK+ の上に Clutter を載せて、その上に GTK+ を置く。
という奇妙な構造だけど他に手段が無い。
下記はそのまま動くようにしたものを抜き出ししてみた。
#!/usr/bin/gjs const GObject = imports.gi.GObject; const Gtk = imports.gi.Gtk; const Clutter = imports.gi.Clutter; const GtkClutter = imports.gi.GtkClutter; var ClWindow = GObject.registerClass({ GTypeName: 'ClWindow' }, class ClWindow extends Gtk.Window { _init() { super._init(); this.is_fullscreen = false; // actor this.actor = new Clutter.Actor(); // Fullscreen Header and Actor this.upperbar = new Gtk.HeaderBar({ no_show_all: true, valign: Gtk.Align.START }); this.upperActor = new GtkClutter.Actor({ contents: this.upperbar }); this.upperActor.hide(); // Restore Button let restoreButton = new Gtk.Button({ image: Gtk.Image.new_from_icon_name('view-restore-symbolic', Gtk.IconSize.MENU), visible: true }); restoreButton.connect('clicked', ()=> { this.change_fullscreen(); }); this.upperbar.pack_end(restoreButton); // Embed let embed = new GtkClutter.Embed(); let stage = embed.get_stage(); stage.add_child(this.actor); stage.add_child(this.upperActor); stage.connect('motion-event', (actor, event)=> { if (this.is_fullscreen) { let [, y] = event.get_coords(); // upperbar if (this.is_fullscreen) { if (y <= this.hb_height+10 && !this.upperbar.visible) { this.upperActor.show(); this.upperbar.show(); } else if (y > this.hb_height+10 && this.upperbar.visible) { this.upperActor.hide(); this.upperbar.hide(); } } } }); // box let vbox = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL}); vbox.pack_start(embed, true, true, 0); vbox.connect('size-allocate', (vbox, allocation)=> { if (this.is_fullscreen) { this.upperActor.set_size(allocation.width, this.hb_height); this.upperbar.set_size_request(allocation.width, this.hb_height); } }); // Double Click Fullscreen vbox.connect('button-press-event', (widget, event)=> { if (event.get_event_type() == 5) { this.change_fullscreen(); } return true; }); // main let hb = new Gtk.HeaderBar({show_close_button: true}); this.set_titlebar(hb); this.add(vbox); this.connect('delete-event', ()=> {Gtk.main_quit();}); this.resize(300, 300); this.show_all(); this.hb_height = hb.get_allocated_height(); } change_fullscreen() { this.is_fullscreen = this.is_fullscreen === false; if (this.is_fullscreen) { this.fullscreen(); } else { this.unfullscreen(); if (this.upperbar.visible) { this.upperbar.hide(); this.upperActor.hide(); } } } }); Gtk.init(null); GtkClutter.init(null); let w = new ClWindow(); Gtk.main();
やっぱり長いな。
細かい解説はしないから自力で解析してね。
注意点は GtkWindow の motion-notify-event で処理しないこと。
ドロップしたメニューを選ぼうとマウスを動かすとメニューが消える罠がwwwww
って Comipoli 0.3.5 がそうなっているということに今気が付いた!
Comipoli は全部 GTK+ なんだが、同じ手段は使えない。
さて困った、eog みたいにメニューを出さないという手もあるけど。