fvwm3のインストール

「FVWM version 3 — the successor to fvwm2」が公開されているが、現在UbuntuにはFvwm3のパッケージは存在しない。https://packages.ubuntu.com/

待っていても、パッケージでは提供されないのだろうか。と言う訳でコンパイルしインストールを行う。

https://github.com/fvwmorg/fvwm3/blob/master/dev-docs/INSTALL.md ここを参考に、Core dependenciesとOptional dependenciesをインストールしておく。
librsvg-devがなくてlibrsvg2-devがあったので、これをインストールしてみた。大丈夫?

#!/bin/bash
while read line
do
echo -e "\e[32;1m$line\e[m"
sudo apt install $line -y
done << EOF
libevent-dev
libx11-dev
libxrandr-dev
libxrender-dev
libxt-dev
asciidoctor
libfontconfig-dev
libfreetype6-dev
libfribidi-dev
libncurses5-dev
libpng-dev
libreadline-dev
librsvg2-dev
libsm-dev
libxcursor-dev
libxext-dev
libxft-dev
libxi-dev
libxpm-dev
sharutils
EOF

準備ができたらgitからダウロード

git clone https://github.com/fvwmorg/fvwm3.git

あとはInstalling From Gitの手順で

./autogen.sh
./configure --enable-mandoc 
make

configureでWith Golang support? noになったが、まぁいいか。

じゃないわ! FvwmPrompt — a new module written in golang: ./configure --enable-golang needed at compile time だとさ。
で、以下のconfigureでyesになった。

./configure --enable-mandoc --enable-golang

つまりこういう事である。

/autogen.sh && ./configure --enable-mandoc --enable-golang && make -j4

さらに改良。Makefileに、CPPFLAGS = -march=amdfam10 追加。k10なのよ。
でmake clean && make -j4

sudo make install

インストールできたら、 .xinitrcのfvwm2の部分をfvwm3に書き換えて。startxする。
何が変わったのかはここを読むといい。https://github.com/fvwmorg/fvwm3/releases

fvwm3では、Strokeコマンドがなくなった。libstroke support has been removed.だと。
あまり使わないので、まぁ影響はないけど。キーとマウスクリックで対応できるでしょうから。Strokeは設定ファイルからコメントアウト。あとEdgeResistance 30 30でエラー、引数は1つのみが正解。何か2つ目の引数って効果あるの?ってずっと思ってた。EdgeResistance 30が正しいと、-vオプションのエラーログで分かった。

logを取るには.xinitrcで起動時に fvwm3 -v と -vのオプションを付けると、$HOME/.fvwm/fvwm3-output.log が作られる。起動中では pkill -USR2 fvwm3 ができる。

Fvwm3のモジュールは以下のとおり

FvwmAnimate
FvwmAuto
FvwmBacker
FvwmButtons
FvwmCommandS
FvwmConsole
FvwmConsoleC
FvwmEvent
FvwmForm
FvwmIconMan
FvwmIdent
FvwmMFL
FvwmPager
FvwmPerl
FvwmRearrange
FvwmScript
FvwmTalk

fvwm2.6.8のモジュールは以下の通り。○は存続、×は消滅したもの。

FvwmAnimate ○
FvwmAuto ○
FvwmBacker ○
FvwmBanner ×
FvwmButtons ○
FvwmCascade ×
FvwmCommandS ○
FvwmConsole ○
FvwmConsoleC ○
FvwmConsoleC.pl ×
FvwmCpp ×
FvwmEvent(FvwmAudio) ○
FvwmForm ○
FvwmIconMan ○
FvwmIdent ○
FvwmM4 ×
FvwmPager ○
FvwmPerl ○
FvwmProxy ×
FvwmRearrange ○
FvwmScript ○
FvwmTalk ○
FvwmTile ×

fvwm2.6.8はfvwm2.6の最終安定版ですね。
こちらでも絶版があるわけですが。FvwmTaskBarが無くなったのが大きかったかな。

  - Some fvwm modules have been removed:
      - FvwmDragWell   (no replacement)
      - FvwmGTK        (no replacement)
      - FvwmSave       (no replacement)
      - FvwmSaveDesk   (no replacement)
      - FvwmScroll     (no replacement)
      - FvwmTabs       (no replacement, never worked anyway)
      - FvwmTaskBar    (use FvwmButtons)
      - FvwmTheme      (in core of fvwm as colorsets)
      - FvwmWharf      (use FvwmButtons)
      - FvwmWinList    (use WindowList command)
      - FvwmWindowMenu (use WindowList command)
      - FvwmIconBox    (use the IconBox style instead)

FVWMを使う理由

この時代に、なぜFVWMを使っているのだろうか。
絶滅危惧種的存在のXウィンドウマネージャであるし。使う人間も絶滅危惧種的レアな人々であろうし。でも信じたいFVWMが存続し、進化し続けることを。
なぜなら、FVWMには、世界中のレアでコアな人間の希望と情熱があるからである。

という訳でFVWMが使える理由。

  • カスタマイズができる
  • 環境に依存しない
  • 環境を好みに作れる
  • 画面をとても広く使える
  • ハイバネーションを使っての利用は、やりっ放しの続きができる感がある。
  • コツコツ積み上げる感が良い
  • 自分の知恵を組み込める
  • 成長することができる
  • 簡単に済ますことができない
  • 普通ではない、そこが魅力

あえて言うと、使えない理由。

  • Linuxのノービスユーザーには、難解であろう。
  • 情報が少ない、情報が古い
  • どこから、どうカスタマイズしたら良いか分からない
  • 初期の設定だと、とてもださい。以前のよりは改良されているのだが。

そんなとこですかね。

fvwm3のManual Pageですが。驚異的な莫大な量です。manの歴代一位の長さと言えますか。親切丁寧に書かれてるんですが。まぁすごいですよね。

https://github.com/fvwmorg/fvwm3/blob/master/doc/fvwm3/fvwm3.adoc

FVWM2のPositionPlacement

FVWM2でFirefoxを使用していると。URLの左横の鍵アイコンをクリックして、安全な接続の詳細を表示するをクリックするとページ情報が新たなウィンドウで表示されるのだが。わしは、Style * PositionPlacement UnderMouse と設定しているので、左上のマウスのそばにウィンドウが表示される訳だが、これを画面の中央に表示させたい。

この表示させたいウィンドウをIdentifyで調べると Class: は Firefoxで Resource:は Browserであった。それで Style “Browser” PositionPlacement Centerと設定したのだが、中央に表示されるはずが、表示されない。困ったものだ。

他の方法として Style “Browser” PositionPlacement 50-50w 50-50w と設定したところ。中央に表示されてうまく行ったのである。この50-50wの意味は、左はX方向、右はY方向。最初の50は50%を表し、50 50だと、ウィンドウの左上の点が画面の50%50%に来るので全体としては右下にずれて表示が見える。これを防ぐためにウィンドウ左上の点を左上に移動させないとならない。これが-50wという記述をつけるとできるのだ。意味はウィンドウサイズの50%をマイナスするという事なのである。FVWMの座標の原点0 0は左上にある。

XDG Menusの動作が変

Regenerationを行っても再起動すると、古いMenuに戻ってしまう。設定が変わった?

これを解決するのには、古い .XDGMenuファイルを削除して新しく .XDGMenuのファイルを作ると、正常に動作するようになった。

fvwmのメニューからFvwmForm-XDGMenu-Config(Module FvwmPerl -l fvwm-menu-desktop-config.fpl)(FvwmCommand Module FvwmPerl -l fvwm-menu-desktop-config.fpl) を起動 Output pathを .fvwm2rcの .XDGMenuのファイルを読み込むパスと同じパスに設定する。
ちなみにこのモジュールのパスは/usr/share/fvwm/fvwm-menu-desktop-config.fplである。解析するにはここから。

古い環境からの .XDGMenuは削除し、XDGRegenで新しく作るのが良いという事であった。

FVWM2のログを取る時

startxからFVWMを起動してるので、 .xinitrcの最後のexecの行に、-debug以下を追加する。
要らなくなったら消す。

exec dbus-launch --sh-syntax --exit-with-session fvwm2 -debug > ${HOME}/fvwm.log 2>&1


.xinitrcの先頭に dbu-launchを行うのが良いという案もあるのだが。自分の環境だと、gnome-terminalでfcitxが入力できないので、最後の行のfvwm2の起動時に行った方が良い。下記は良くなかった例。

eval "$(dbus-launch --sh-syntax --exit-with-session)"
#
# その他記述
#
exec fvwm2 -debug > ${HOME}/fvwm.log 2>&1

dbusについては以下を参考に https://www.silex.jp/blog/wireless/2017/01/d-bus.html

fcitxとgnome-terminalの挙動を考慮すると以下の.xinitrcになった。

export DefaultIMModule=fcitx
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export XDG_CONFIG_HOME=$HOME/.config
xscreensaver &
exec dbus-launch --sh-syntax --exit-with-session fvwm2 -debug > ${HOME}/fvwm.log 2>&1

fvwm3 をインストールしたのでログがアペンディングモードで取れる。こっちを利用するので変える。

Enables debug logging. Writes in append mode to fvwm log file, which is ~/.fvwm/fvwm3-output.log by default.

#exec dbus-launch --sh-syntax --exit-with-session fvwm2 -debug > ${HOME}/fvwm.log 2>&1
exec dbus-launch --sh-syntax --exit-with-session  fvwm3 -v

こちらのログの方が、詳しく取れてるし、-debugは要らないって事だな。

fcitxの起動は、FVWMのStartFunctionに記入しfvwmが立ち上がってから起動する順番にした。

+ I exec fcitx-autostart &

stalonetrayをインストールしFvwmButtonsの中にSwallowとしてシステムトレイアイコンを表示させた。fcitxの状態ウィンドウ(左にペンギンのアイコンがあるやつ)をSwallowしようとしたが、できなかった。移動できるのでFvwmButtonsのあたりに移動しておく。位置は保存できているので、fvwmを再起動しても、そこにあるので良しとする。

*FvwmButtons(Swallow(NoClose,UseOld)  "stalonetray" 'Exec exec stalonetray' )

WordPressの表示が不調

タイトルは表示されるが、本文が表示されない。

なぜだろうか。

PHP バージョン   7.4.16  に変えたのが原因か?

これが原因だった。7.1に変えたら本文が表示された。
どこかを修正する要ができたようだ。

プラグインをオンオフして確認したら、1つのプラグインが原因だったようだ。

Linuxをどう捉えるか

再びLinuxをどう捉えるかを考える。古いPC構成での活用、運用を通してのLinuxの体験を行ってみようと言う、原点に帰った気分でのLinuxの使用を行ってみる。

そこで構成したのが以下の仕様である。

OS: Ubuntu 21.04 hirsute
Kernel: x86_64 Linux 5.11.0-36-generic
Uptime: 1h 53m
Packages: 1880
Shell: bash
Resolution: 1920x1080
WM: FVWM
GTK Theme: Yaru-light [GTK3]
Icon Theme: DMZ-White
Disk: 26G / 106G (26%)
CPU: AMD A6-3500 APU with Radeon HD Graphics @ 3x 2.4GHz
GPU: AMD SUMO (DRM 2.50.0 / 5.11.0-36-generic, LLVM 12.0.0)
RAM: 1596MiB / 1925MiB

CPUは、AMD A6-3500を使用。GPUコアを備えたCPUでCPU部分に動作クロック2.1GHzのCPUコアを3つ備える。Socket FM1, Clock Speed 2.1 GHz Max Turbo Speed 2.4 GHz, Thermal Design Power 65 W , Cache Memory Details L2 – 3 MB – 3 x 1 MB, AMD Radeon HD 6530D Base Frequency 443 MHz
2011年8月に販売が開始された。

https://wiki.gentoo.org/wiki/Radeon

bookmarks.json 重複URIの削除

Mozilla Firefoxのbookmarkの解析を進めているのだが、今回は重複したURIの削除を行いたい。すべてのブックマークで表れる、エディターで手動でも行えるのだが。フォルダー毎に行うのと、重複が多いので手動では時間がかかる。bookmarks.jsonの解析を進めるのを兼ねて、スクリプトで行なってみる。jsonが扱いやすく、配列処理のコマンドがそろっているphpを使用している。
Firefoxからバックアップして出力させたbookmarks.jsonファイルを読み出して配列に代入し、その配列で処理を行いbookmarks.jsonのファイルを出力する。Firefoxで編集されたそのファイルを復元するで読み込ませて正常に表示できて、重複が消えていれば成功である。

今までやってきたこと。bookmarks.jsonの解析。phpでの配列への代入。それをファイルへ出力し編集。jsonファイルは直接編集しづらい。編集したファイルをbookmarks.jsonに変換しFirefoxde復元でbookmarkとして読み込ませた。

ここまではできる。

これからは配列から、別の配列にURIを代入し重複したURIを見つける。もとの配列から重複した配列を削除し、jsonファイルにする。ここまで行いたい。

GTK+でファイルを選ぶ、gtk_file_chooser_dialog_new

GUIでファイルを探す処理に、GTK+を利用してみよう。

プログラムでファイルを選ぶ場合、あらかじめシェルかファイラーを用い、ファイル名を正確に代入する必要になる。選んだファイル名を返す、単純なGUIのプログラムがあれば汎用できるので、便利である。今回は、GTK+というツールボックスを使用して、GUIでファイルを探すプログラムの制作を行ってみよう。
設定として、簡単で単純なプログラム。汎用性が高いこと。カスタマイズ可能。GTK+の学習を目的とする。

filechooser.c

#include <gtk/gtk.h>
 
int main(int argc, char *argv[]){
    GtkWidget *dialog;
    gtk_init(&argc, &argv);
    
    GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
    gint res;
    
    dialog = gtk_file_chooser_dialog_new ("Open File",
                                          NULL,
                                          action, 
                                          ("Cancelする"),
                                          GTK_RESPONSE_CANCEL,
                                          ("Openする"),
                                          GTK_RESPONSE_ACCEPT,
                                          NULL);
    
    res = gtk_dialog_run (GTK_DIALOG (dialog));
    if (res == GTK_RESPONSE_ACCEPT)
    {
        char *filename;
        GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
        filename = gtk_file_chooser_get_filename (chooser);
        g_print("%s\n",filename);
        //open_file (filename);
        g_free (filename);
    }
         gtk_widget_destroy (dialog);
    
    return 0;       
    
}

コンパイルは以下で。

gcc filechooser.c -o filechooser `pkg-config --cflags --libs gtk+-3.0`

エラーが出る

Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.

gtk_dialog_run (GTK_DIALOG (dialog)); このエラーはで生じてる。
gtk_file_chooser_dialog_new の二番目の引数、NULLだと生じるのか?
そのようだった。main関数から、呼び出すと消えた。

#include <gtk/gtk.h>
 
int file_selection_dialog(GtkWidget *window ,gchar *str){
    GtkWidget *dialog;

    GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
    gint res;;
    
    dialog = gtk_file_chooser_dialog_new ("Open File",
                                     GTK_WINDOW (window), 
                                      //NULL,
                                      action,
                                      ("Cancel"),
                                      GTK_RESPONSE_CANCEL,
                                      ("Open"),
                                      GTK_RESPONSE_ACCEPT,
                                      NULL);
    GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
    gtk_file_chooser_set_current_folder (chooser,str);
    res = gtk_dialog_run (GTK_DIALOG (dialog));
    if (res == GTK_RESPONSE_ACCEPT)
    {
        char *filename;
        filename = gtk_file_chooser_get_filename (chooser);
        g_print("%s\n",filename);
        g_free (filename);
  }
  gtk_widget_destroy (dialog);
}

 int main(int argc, char** argv){
    GtkWidget *window;
    gtk_init(&argc,&argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "destroy",G_CALLBACK(gtk_main_quit), NULL);
    file_selection_dialog(window, argv[1]);
    return 0;
}

main関数とは、別に関数を作り、mainから呼び出すと、GtkDialog mapped without a transient parentのエラーは消えた。mainの中でgtk_file_chooser_dialog_newウィジェットを実行してもエラーがでない方法がありそうだが。組み合わせをいじってみて、mainの中でも動くようになった。改めてみると、単純な表現であるが、初心者が戸惑うツボが垣間見れる。

#include <gtk/gtk.h>
 
int main(int argc, char *argv[]){
    
    GtkWidget *dialog;
    GtkWidget *window;
    
    gtk_init(&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
    gint res;
    
    dialog = gtk_file_chooser_dialog_new ("Open File",
                                          GTK_WINDOW (window),
                                          GTK_FILE_CHOOSER_ACTION_OPEN,
                                          ("Cancelする"),
                                          GTK_RESPONSE_CANCEL,
                                          ("Openする"),
                                          GTK_RESPONSE_ACCEPT,
                                          NULL);
 
    GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
    if (argv[1])
        gtk_file_chooser_set_current_folder (chooser,argv[1]);

    res = gtk_dialog_run (GTK_DIALOG (dialog));
    if (res == GTK_RESPONSE_ACCEPT)
    {
        char *filename;
        filename = gtk_file_chooser_get_filename (chooser);
        g_print("%s\n",filename);
        g_free (filename);
    }
    
    return 0;   
    
}

実行すると、引数のディレクトリーを指定できるので、そのところで開く。
ファイルを選ぶと、標準出力にファイル名を出すようしにした。

シェルスクリプトから呼び出すと、応用できる範囲は広い。

set filePath [exec /home/user/gtk/filechooser /home/user/Archives/Photos/Image]

このように、tclでfilePathにファイル名を代入することができる。Tkで使ってた、tk_getOpenFile をこちらに変えたのである。Tkではプレビューがないので画像ファイルは、呼び出して表示と手間がかかっていた。この方法だとプレビューと言うか、アイコンが見えるのあるが……。小さい。まったく小さい。大きさ変えられないし。もっと大きなアイコン表示ができる?プレビューが同じ窓でできない?

You can add a custom preview widget to a file chooser and then get notification about when the preview needs to be updated. To install a preview widget, use Gtk.FileChooser.set_preview_widget(). Then, connect to the Gtk.FileChooser ::update-preview signal to get notified when you need to update the contents of the preview.

gtk_file_chooser_set_preview_widget()を使ってみた。

#include <gtk/gtk.h>
 
static void
update_preview_cb (GtkFileChooser *file_chooser, gpointer data)
{
  GtkWidget *preview;
  char *filename;
  GdkPixbuf *pixbuf;
  gboolean have_preview;

  preview = GTK_WIDGET (data);
  if (filename = gtk_file_chooser_get_preview_filename (file_chooser))
  {
  pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 256, 256, NULL);
  have_preview = (pixbuf != NULL);
  g_free (filename);

  gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
  if (pixbuf)
    g_object_unref (pixbuf);

  gtk_file_chooser_set_preview_widget_active (file_chooser, have_preview);
}
}
 
 
 int main(int argc, char *argv[])
 {
    
    GtkWidget *dialog;
    GtkWidget *window;
    GtkWidget *preview;
    
    gtk_init(&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
    dialog = gtk_file_chooser_dialog_new ("Open File",
                                          GTK_WINDOW (window),
                                          GTK_FILE_CHOOSER_ACTION_OPEN,
                                          ("Cancelする"),
                                          GTK_RESPONSE_CANCEL,
                                          ("Openする"),
                                          GTK_RESPONSE_ACCEPT,
                                          NULL);
    preview = gtk_image_new ();
    GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
    gtk_file_chooser_set_preview_widget (chooser, preview);
    g_signal_connect (chooser, "update-preview",
		    G_CALLBACK (update_preview_cb), preview);

    if (argv[1])
        gtk_file_chooser_set_current_folder (chooser,argv[1]);
    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
    {
        char *filename;

        filename = gtk_file_chooser_get_filename (chooser);
        g_print("%s\n",filename);
        g_free (filename);
    }
     gtk_widget_destroy (dialog);
     
    return 0;   
    
}

これだと画像を選択すれば、右にプレビューが表示されるので便利だ。

https://developer.gnome.org/gtk3/stable/GtkFileChooserDialog.html#gtk-file-chooser-dialog-new
https://developer.gnome.org/gtk3/stable/GtkFileChooser.html
https://lazka.github.io/pgi-docs/Gtk-3.0/interfaces/FileChooser.html

追加
Couldn’t connect to accessibility bus: Failed to connect to socket /tmp/dbus
が出現するのを消すには、

export NO_AT_BRIDGE=1

を実行しておく、bashrcに記載しておく。fvwmのメニューの中で実行して、エラーが出るので、wish中に

set ::env(NO_AT_BRIDGE) 1

を追加するとエラーが出なくなった。dbusのバグのようだが。