投稿者「sasakima-nao」のアーカイブ

GTK4: HeaderBar

GTK4 では GtkHeaderBar の set_title が無くなった。
というよりタイトル表示部が Widget に固定されてしまった。

いや set_title 関数は自分で定義すればいい。
後は Widget として GtkLabel を入れれば今までのようにはできる。

とはいえそれじゃ普通のラベルだから Bold 化とかしなきゃいけないな。
サブタイトルは薄く小さくしなきゃだし、CSS でやるのかな?

そういえばサブタイトルは gnome-text-editor が実装している。
どうやっているのかソースを覗いてみよう、GPL っていいですね。

src/editor-window.ui ? main ? GNOME / gnome-text-editor ? GitLab

コレを真似すればいいんだけど、attributes って何だ?
それを解っていないと定義も糞もないコピペアプリにしかならない。
調べると Pango 関連らしい、よしコードで同じになるように書いてみよう。

#!/usr/bin/env python3

from gi.repository import Gtk, Pango

class ComipoliHeaderBar(Gtk.HeaderBar):
    def __init__(self):
        Gtk.HeaderBar.__init__(self)
        # LR Button
        self.lr_button = Gtk.ToggleButton(label='L<-R', can_focus=False, focus_on_click=False)
        self.pack_start(self.lr_button)
        # Grid Button
        self.grid_button = Gtk.Button(icon_name='view-grid-symbolic', can_focus=False, focus_on_click=False)
        self.pack_start(self.grid_button)
        # Main Title
        bold = Pango.attr_weight_new(Pango.Weight.BOLD)
        alistm = Pango.AttrList()
        alistm.insert(bold)
        self.title = Gtk.Label(label='', single_line_mode=True, ellipsize=Pango.EllipsizeMode.END, attributes=alistm)
        # Sub Title
        subs = Pango.attr_scale_new(0.8222)
        suba = Pango.attr_foreground_alpha_new(32767)
        alists = Pango.AttrList()
        alists.insert(subs)
        alists.insert(suba)
        self.subtitle = Gtk.Label(label='--', single_line_mode=True, ellipsize=Pango.EllipsizeMode.END, attributes=alists)
        # Title pack
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, valign=Gtk.Align.CENTER)
        box.append(self.title)
        box.append(self.subtitle)
        self.set_title_widget(box)
        # Menu Button pack @ after Window.__init__

    def set_title(self, text):
        self.title.set_label(text)

    def set_subtitle(self, text):
        self.subtitle.set_label(text)

header_bar

まったく同じになろうようにしてみた、滅茶苦茶面倒だった。
GtkBuilder はあんな単純表記を読んでコレをやっているのか、凄いんだな。
とにかく、attributes の指定は Pango の関数と値の省略表記ですね。

gnome-text-editor は GtkCenterBox を挟んでいるけどさ。
アレは別の用途なのでこういう場合はいらない。

そういえばタイトルが長い場合に収めるためウインドウが大きくされるのも防がないと。
ellipsize プロパティを定義すると自動でやってくれるみたい、なるほど。
後はウインドウが非アクティブになった時にタイトルを薄くすればオケ。

残りの GTK4 化は今までに書いたことの応用でイケそうだ。
何か見つけたら書いていきます。

Gdk.Cursor.new_from_name

ただ、矢印だけのカーソルは無くなってしまったようで。
とはいえ、そもそも作った本人はマウスでページめくりをしたことが無い。
ということで GTK4 版はマウスカーソルの変更は無しにする予定。

えっ夏鳥?昨日も今日もオケラでションボリしてます。

GTK4: Menu

現在 Comipoli の GTK4 化の準備をしているんだが。

まずメニュー。
GTK3 は GtkModelButton を GtkBox に入れソレを GtkPopoverMenu に。
だったけど GTK4 は GtkModelButton が廃止されている。

なので GTK4 は GMenuItem を GtkPopoverMenu に入れろとあるんだが。
GMenuItem をコードで作る方法はどこにも書いていない。

Gtk.PopoverMenu

しかたがないので XML で作る。

それから、GtkButton の image プロパティが廃止されていた。
代わりに icon-name が追加、つまり GtkImage を時前で用意しなくてもいい。

#!/usr/bin/env python3

from gi.repository import Gtk

menu_model = '''
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id='comipoli-menu'>
  <section>
    <item>
      <attribute name='label' translatable='yes'>_Open</attribute>
      <attribute name='action'>app.new_file_action</attribute>
    </item>
    <item>
      <attribute name='label' translatable='yes'>_New Window</attribute>
      <attribute name='action'>app.new_window_action</attribute>
    </item>
    <item>
      <attribute name='label' translatable='yes'>_Preference</attribute>
      <attribute name='action'>app.preference_action</attribute>
    </item>
    <item>
      <attribute name='label' translatable='yes'>_Keyboard Shortcut</attribute>
      <attribute name='action'>app.shortcut_action</attribute>
    </item>
    <item>
      <attribute name='label' translatable='yes'>_About</attribute>
      <attribute name='action'>app.about_action</attribute>
    </item>
    <item>
      <attribute name='label' translatable='yes'>_Quit</attribute>
      <attribute name='action'>app.quit_action</attribute>
    </item>
  </section>
</menu>
</interface>
'''

class ComipoliMenuButton(Gtk.MenuButton):
    def __init__(self):
        ''' GTK3
        # MenuIten
        menu_open  = Gtk.ModelButton(active=True, action_name='app.new_file_action', text='_Open', use_markup=True)
        menu_new   = Gtk.ModelButton(active=True, action_name='app.new_window_action', text='_New Window', use_markup=True)
        menu_pref  = Gtk.ModelButton(active=True, action_name='app.preference_action', text='_Preference', use_markup=True)
        menu_kbd   = Gtk.ModelButton(active=True, action_name='app.shortcut_action', text='_Keyboard Shortcut', use_markup=True)
        menu_about = Gtk.ModelButton(active=True, action_name='app.about_action', text='_About', use_markup=True)
        menu_quit  = Gtk.ModelButton(active=True, action_name='app.quit_action', text='_Quit', use_markup=True)
        # Box
        vbox = Gtk.Box(visible=True, margin=10, orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(menu_open, False, False, 0)
        vbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), False, False, 0)
        vbox.pack_start(menu_new, False, False, 0)
        vbox.pack_start(menu_pref, False, False, 0)
        vbox.pack_start(menu_kbd, False, False, 0)
        vbox.pack_start(menu_about, False, False, 0)
        vbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), False, False, 0)
        vbox.pack_start(menu_quit, False, False, 0)
        # PopoverMenu
        self.popover = Gtk.PopoverMenu()
        self.popover.add(vbox)
        '''
        builder = Gtk.Builder.new_from_string(menu_model, len(menu_model))
        model = builder.get_object('comipoli-menu')
        self.popover = Gtk.PopoverMenu.new_from_model(model)
        ''' GTK3
        #image = Gtk.Image(icon_name='open-menu-symbolic')
        #Gtk.MenuButton.__init__(self, can_focus=False, focus_on_click=False, image=image, visible=True, popover=self.popover)
        '''
        Gtk.MenuButton.__init__(self, can_focus=False, focus_on_click=False, icon_name='open-menu-symbolic', visible=True, popover=self.popover)

    def do_toggled(self):
        if self.props.active:
            self.popover.show_all()
        else:
            self.popover.hide()

丸ごと作り替えだった。

menu_button

そうそう、GtkShortcutsWindow の pack_start が廃止。
かつ GtkBox のサブクラスに、なので append で配置する。
orientation=Gtk.Orientation.HORIZONTAL 指定を忘れずに。
最初縦に配置されてしばらく悩んでしまった。
そんなことより。

shortcut

GtkShortcutsWindow を表示すると上記エラーを吐く。
もちろんサーチバーは出ない、これバグだよな。
Fedora 36 では修正されているのかな?

まだ色々とあるけど解決していないのでまた今度。

Flower

今日は市民四季の森へ、夏鳥を求めて。

enaga

エナガ、夏鳥じゃないけどなんか久々に見た。
おちょぼ口がカワイイよね。

kogera

コゲラ、夏鳥じゃないけどおなかが撮れたのは初めてだ。
いつも横向きばかりだったのでなんか新鮮。

後はホーホケキョとか色々な鳥が鳴いていたけど見えない!
夏鳥は?まあ何も撮れなかったよりはマシか。
そんなことより。

bara

薔薇がもう咲いていることに驚いた。
三月後半に梅を撮りに来た時は土に枝が刺さっていただけだったのに。

lib

リビングストンデージーっていう花らしい。
最初造花かと思った、なんだこの蛇の目傘みたいな花弁は。

花もいいな、今年は花メインでいこうかな。
歳をとると花が好きになるのは自然なことなんだなって。

というかカメラ二台体制にして本当に良かった。
レンズ交換しなくてもいいなら気軽にコイツもってなるのよね。

bash 5.1

Fedora 35 の bash は 5.1.8 である。
何を今更だが 5.1 で大文字小文字変換に新たな手段が追加されていた。
U u L 指定らしいんだけど、どう指定すればいいのかはドコにも書いていない。

How to convert a string to lower case in Bash? – Stack Overflow

やっと見つけた、fedorqui さんありがとう。

#!/bin/sh

pen='olympus PEN'

echo ${pen@U}
#=> OLYMPUS PEN

echo ${pen@L}
#=> olympus pen

echo ${pen@u}
#=> Olympus PEN

結局ブレースが必要なのか。
zsh みたく $pen:U とはできなかったのだろうか。
u は先頭文字以外を無視するだけだし使い道が無さそう。

#!/bin/sh

pen='olympus PEN'

echo ${pen^^}
#=> OLYMPUS PEN

echo ${pen,,}
#=> olympus pen

echo ${pen~~}
#=> OLYMPUS pen

今までのとタイプ数が変わっていないし、反転指定は無いし。
いやまあ、こんな手段もありますよってことで。

ということでコレを Tips ページに追記して。
こないだ調べたシェル関連も忘れないうちに追記して。
ついでに GTK4 ページのできているところまでもアップロードして。

よくみたら前の更新は昨年の今日だった、放置しすぎだ!
そんなこんなで、一年ぶりに本サイト更新です。

mpv: Ctrl+q @ Close all MPV Windows

Fedora で mpv を使って困ること。
Ctrl+q で複数起動したすべての mpv を終了できないこと。

だって GNOME のアプリは全部そうなっているんだもの。
そういえば Chrome が Fedora では終了できないな、狐はできるのに。
コレは GNOME アプリ同様 Ctrl+w 連続押しで代用できるのでまあよし。

macOS では command+q ですね、サードパーティすら全部。
そりゃ macOS はウインドウを全部閉じても終了できないんだから必須機能。
唯一 Finder だけが不可、ファイルマネージャは常に起動しているし。

でも Nautilus は Ctrl+q で全部のウインドウを閉じてくれる動作をする。
そんなこんなで、凄く気になるんですよ。

で、よく考えたら UNIX には killall コマンドがあった。
Linux ではコマンドと GUI の区別が無いんだから使えるかも。
ということで Lua スクリプト。

-- ~/.config/mpv/scripts/mpv_ctrl_q.lua

-- Ctrl+q @ Close all MPV Windows.
function on_close_all()
    os.execute('killall mpv')
end
mp.add_key_binding('Ctrl+q', 'close_all_func', on_close_all)

これをスクリプトディレクトリに突っ込んで。
おぉ自分を含めて全部終了してくれる、やったね。
macOS では GUI は区別されているから無理だと思う。
統一されたキーボード操作が無い某 OS はどうでもいいね。

ついでに、最近の mpv osc 設定。
シークバーは QuickTime のようにフローティングもできると知った。

# ~/.config/mpv/script-opts/osc.conf

# 動画に合わせた OSC リサイズ無効
vidscale=no

# 薄くする
boxalpha=180

# 常にトータル時間
timetotal=yes

# タイトルはファイル名 -- タイトル名
title=${filename} -- ${media-title}

# シークバーのみに、弄る時に枠外になるのを防げる
layout=slimbox
seekbarstyle=diamond
valign=0.95

kogera

てかシークバーだけにできるんだ、こりゃいいわ。
だって osc ってシークバーしか使わないよねみんな。

kogera

QuickTime も再生ボタンとか消せないかなぁって。
macOS では動画はほとんど見ないので QuickTime のままです。
ちなみに QuickTime だけで動画の切り貼りやリサイズ保存ができる。
筆者の編集範囲ならコイツだけで完了するので重宝していたりします。