フルスクリーン時にマウスカーソルを上に持って行くとヘッダーがヒョッコリ。
という処理は 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 みたいにメニューを出さないという手もあるけど。






