Empty the Clipboard. and Set Clipboard Text

Gedit の GtkToolbar を見ていて気が付いた。

Clipboard が空の時に Gedit を起動。
ウエブブラウザ等の別アプリで Ctrl+C を押し何か文字列をコピー。
すると Gedit の貼り付けアイコンが自動的に有効になる。
当然 Ctrl+V で貼り付け可能。

リアルタイムで監視していたんだね。
クリップボードに何か入っているかのインジケータとして使える、便利だ。

それはともかく、ウエブブラウザを終了してもクリップボードに残っている。
あれ?以前はコピー元を終了すると使えなくなっていたはずだが。
GNOME2 時代の古い記憶だから今は変わっているのかもしれない。

よし実験、ちなみに今後このブログは Python3 コードで書きます。

#!/usr/bin/env python3

from gi.repository import Gtk, Gdk

"""
    Empty the Clipboard.
"""

display = Gdk.Display.get_default()
clipboard = Gtk.Clipboard.get_for_display(display, Gdk.SELECTION_CLIPBOARD)
clipboard.set_text("Failed", -1)

だめジャン!
と思ったけど Gedit のツールバーを見ると貼り付けアイコンが無効になっている。
つまりこうするとクリップボードを空にできるってことみたい。

不本意だがクリップボードを空にする方法を発見してしまった。
使い道はともかく。

何故だろう、我が clipoli と同じコードを書いているのに。
もしかして mainloop が必用なのだろうか。

clipoli から mainloop を通る最小限コードを抜き出して実験。

#!/usr/bin/env python3

from gi.repository import Gtk, Gdk

"""
    Success additional main loop
"""

class ClipboardTest(Gtk.Menu):
    def __init__(self):
        Gtk.Menu.__init__(self)
        menuitem = Gtk.MenuItem.new_with_mnemonic("_Set Clipboard Text")
        menuitem.connect("activate", self.on_menuitem)
        self.append(menuitem)
        self.show_all()
        self.popup( None, None, None, None, 0, 0)

    def on_menuitem(self, widget, data=None):
        display = Gdk.Display.get_default()
        clipboard = Gtk.Clipboard.get_for_display(display, Gdk.SELECTION_CLIPBOARD)
        clipboard.set_text("Sucsess", -1)
        Gtk.main_quit()

ClipboardTest()
Gtk.main()

これなら上手くいく、やはり一旦メインループを回す必用があるみたい。
つまりループ無しだと set_text に NULL ポインタが入ってしまうのかな。
とにかく挙動は解ったので内部の細かいことはイイや(ぉい!

しかし gtk_main_quit を呼ぶ必用があるのでコードが冗長だ。
メニューを出さなくても呼べる何か上手い手段は、、、

そうだ GtkApplication があるじゃないか。

#!/usr/bin/env python3

from gi.repository import Gtk, Gdk

"""
    Put the text to clipboard.
"""

class App(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self)
        self.connect("activate", self.on_activate)
        
    def on_activate(self, data=None):
        display = Gdk.Display.get_default()
        clipboard = Gtk.Clipboard.get_for_display(display, Gdk.SELECTION_CLIPBOARD)
        clipboard.set_text("Success", -1)

app = App()
app.run(None)

GtkApplication ならこんなにスッキリなコードに。
クリップボードにスパッと特定文字列を入れるコマンド程度なら簡単に作れるね。

**********

そういうことなら minipoli の Linux バージョンもイケそう。
なんて思ったけど。

ctrl_c

Nautilus で Ctrl+C して Editor で Ctrl+V すると実はフルパス貼り付けができる。
gnome-terminal に DnD する、そこから Ctrl+Shift+C なんて手段もあるし。
GNOME って便利すぎ、デフォルトでコレだもん。
たまに Windows を使うと何も出来なくてイラッとするのは私だけなのか?

何より GetAsyncKeyState に相当する API が Gtk には無いようだ。
minipoli の移植は作るだけムダだしムリっぽいかな。
でも Palepoli 復活という手もあるな、誰も覚えていないだろうけど。

Change in Python3

Y901x を Python3 化してみた。
Python3 って pyc キャッシュは __pycache__ ディレクトリに入るのね。

言語としての一貫性を重視したPython 3の進化 ? @IT

Y901x は gir 以外は sys, os, time の標準モジュールしか使っていない。
多分文字列と割り算さえ気を付ければそれほど変更点は無いだろう。

Python3 はデフォルトが UTF-8 なので coding 指定が不要に。
これで海外の Python 製アプリの動作が変という場合は減ると思う。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

to

#!/usr/bin/env python3

例外はカンマから as に変わり raise も関数(?)になった。

#except Exception, e:
except Exception as e:

#raise ValueError, "hoge"
raise ValueError("hoge")

忘れちゃいけない unicode 関数を使っていた部分は str にして。

#s = unicode(entry.get_text()) # Python2
s = entry.get_text()
i = s.rindex(".")

割り算で整数にならないと困る部分は / を // に書き換えて。
/= も //= にしないといけないのか。
逆に float にキャストしていた部分はキャストを外して。

Python 歴があるなら誰でも知っていることはこれくらいで。

他 Fedora 19 の gir を色々試してみると
GLib.filename_from_uri 関数の動作が Ubuntu 13.04 と同じになった。
Gio.ApplicationFlags.HANDLES_OPEN も使えるようになった。

しかし Gio.ActionEntry が作れず ApplicationMenu は使えないまま。
使えるなら多重起動防止の設定を追加しようと思ったけどまだムリっぽい。
pygobject のバージョンに今後も振り回されるんだろうな。

今頃気が付いたけど inifile8.py に古いものを使っていた。
Python3 互換の文字列フォーマッタ版を随分前に作ったのにアホだ。

思ったより簡単だと変更していたけど問題は文字列や割り算ではなかった。
自然順ソートを行う numsort.py だった。

Python3 には cmp 関数が無い、いやコレの自作だけなら簡単だけど。
sort(), sorted() の引数が違う、てか比較関数が使えない。

ソート HOW TO ? Python 3.3 documentation

自力でクイックソートを作るか cmp_to_key をコピペするかだね。
cmp_to_key 関数を使うとなるとこんな感じでいいようです。

#! /usr/bin/env python3

from gi.repository import GLib, Gio

def sort_func(str1, str2):
    """
        str1.encode("utf8") is not required.
        Not 'cmp' function in Python3
    """
    cmpstr1 = GLib.utf8_collate_key_for_filename(str1, -1)
    cmpstr2 = GLib.utf8_collate_key_for_filename(str2, -1)
    # cmp function
    if cmpstr1 < cmpstr2:
        return -1
    elif cmpstr1 > cmpstr2:
        return 1
    return 0

def cmp_to_key(mycmp):
    """
        http://docs.python.org/3.3/howto/sorting.html # en
        http://docs.python.jp/3.3/howto/sorting.html # Japanese
        Convert a cmp= function into a key= function
    """
    class K(object):
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K

def get_file_numsort_list(dirname):
    """
        param dirname: Directory Full Path Name
        return: List in Numeric Order
    """
    files = []
    d = Gio.file_new_for_path(dirname)
    enum = d.enumerate_children(
            Gio.FILE_ATTRIBUTE_STANDARD_TYPE,
            Gio.FileQueryInfoFlags.NONE,
            None )
    for info in enum:
        if info.get_file_type() == Gio.FileType.REGULAR:
            s = info.get_name()
            if not s.startswith("."):
                if not s.endswith("~"):
                    files.append(s)
    # Python2
    #files.sort(lambda x, y : cmp(GLib.utf8_collate_key_for_filename(x, -1), 
    #            GLib.utf8_collate_key_for_filename(y, -1)))
    #
    # Python3
    files.sort(key=cmp_to_key(sort_func))
    return files

これじゃラムダ式にできない、別にいいけど。
随分コードが長くなってしまったけどアプリケーションは動けばいいのさ。
アーカイブサイズが減った理由がワカラナイ…

GLib.utf8_collate_key_for_filename は str のままイケた。
GLib で文字列として扱う場合は UTF-8 で得られるということみたい。
でも Python 文字列として扱う場合は UCS-4 であるのを意識する必用あり。
でいいのだろうか、いつか落とし穴にはまりそうな気もする。

ついでに PyGI で今更気が付いたこと。

class CToolBox(Gtk.Box):
    def __init__(self):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)

GtkBox は GtkOrientable をインプリメントしているから orientation property がある。
なのでこの指定で GtkBox のサブクラスを作れば GtkVBox と同様になる。
いやプロパティは全部 __init__ の引数にできるのを知ったのは最近だし。

y901x101

とりあえず Python3 化した Y901x 1.0.1 公開。
memopoli の更新をやるべきなんだろうけど、実はもう使っていないのだがどうしよう。

1.0.1 Download (34.0kb)

blog にもリンクを今回から貼ることにする。
需要は無いだろうけど何かの参考になればいいや。

google-chrome 28 libpeerconnection.log

Fedora 19 で google-chrome 28 を起動すると
SELinux is preventing /opt/google/chrome/chrome from create access on the file libpeerconnection.log.
と SELinux に怒られる。
そのうち修正されるだろうと都度解除ボタンを押していたが辛くなってきた。
ポリシーツールもチョロメもまったくアップデートに出てこないし。

SELinux ポリシーを自力変更しようとしたが何故か audit2allow が見つからない。
これじゃトラブルシュートできないよ、手段が変わったのだろうか?

なんとかしたいので libpeerconnection.log で検索してみる。

Ubuntuのlibpeerconnection.logって何? 自分は今、Ubuntu13.04を使っていますが、… – Yahoo!知恵袋

Ubuntu だと SELinux が無いからブロックは無いけどホームに log 生成らしい。
なんだそれ、通信ログだろうけどカレントディレクトリに吐き出しているってこと?
完全に chrome 側のチョンボであるようだ。

ということは SELinux の場合 setsebool する必要でもあるのかな。
つかホーム直下に log ファイルを作られても困るんだが…

Issue 239048 – chromium – libpeerconnection.log file created in CWD – An open-source project to help move the web forward. – Google Project Hosting

そうか、カレントを /tmp に変更してしまえばいいんだ。

sudo gedit /opt/google/chrome/google-chrome

linux_chrome28_fix

SELinux はスルーされ、しっかり libpeerconnection.log は /tmp に生成。

tmp_ls

あぁ普通に起動できる、普通って素晴らしい。
しかし当面は chrome アップデート毎に行う必要があるかも。

生成された libpeerconnection.log のセキュリティコンテキストを見ると
chrome_sandbox_tmp_t とよくワカランものになっている。
サンドボックス領域での通信ログをホームに保存だと SELinux は弾くということか。
テンポラリになら保存できるのならあまり意味が無い気もするんですけど。

Fedora 19 Install (HDD) part3

とうとう Fedora にもデフォルトで Python3 が入るようになった。
そりゃ当然 Python 作者達はいいかげんに移行してほしいだろうけど。

python3_japanese

Python2 の byte 列が単なる str のエイリアスだったのが厳密になっただけだが。
こんな感じで ascii より扱いづらくなるのよね。

それと Gtk+ を使って文字列のやりとりは UTF-8 と UCS-4 を変換しているのかな?
とにかく内部文字列が UCS-4 の言語だと色々とデメリットしか無い気がするが…
Windows だと内部も Python3 も、ついでに C# も UTF-16 だから逆に歓迎だが。
Vala なんて C# 風な言語なのに文字列は ascii なんだよね。

Seed, Gjs は今回もあるけど全然普及しないな…

Gedit で自作の Python 製プラグインがロードできない。
Could not find loader ‘python’ for plugin ‘html_escape’
Python が見つからないってどういうことだよ…
まさかと思って *.plugin のローダーを python3 に変更したら動いた、マジかよ。
公開プラグインは面倒だしトップページからお知らせでお茶を濁すことにする。
スニペットと外部ツールは以前のを ~/.config/gedit からコピペで使えた。

他の我が Python 製アプリはまだ問題なく動くみたい。
PyGst はやはり無くなったか、Y901x は早めに切り替えしてよかった。
どっちにせよ Python3 製に変更しなきゃいけなくなるだろう。

とにかく Fedora で Python を少しでも使っている人は注意してね。

**********

あまりに自然すぎて気が付かなかった。
dconf-editor の説明が日本語表示になっている。

dconf_editor_jp

メニューのカテゴリを変更したいな。
org.gnome.shell app-folder-categories
で指定するみたいだけど
[‘Utilities’, ‘Sundry’, ‘Office’, ‘Network’]
とやっても Office フォルダはできるけどメインメニュー側にも残るしブラウザフォルダは作成すらされない。
‘Network’, ‘Internet’ と 2 つ指定しないとインターネットカテゴリがまとまらない。

Enabling Categories in GNOME 3.8 Shell Application Menu

[‘Utilities’, ‘Games’, ‘Sundry’, ‘Office’, ‘Network’, ‘Internet’, ‘Graphics’, ‘Multimedia’, ‘System’, ‘Development’, ‘Accessories’, ‘System Settings’, ‘Other’]

のように全部カテゴリを指定すると全部まとまる。
/usr/share/applications/*.desktop
指定のカテゴリが複数ある場合は個別だとメインに残るということなのね。
これじゃ全部かデフォルト以外は選べない、あまり意味がない。

Fedora 19 Install (HDD) part2

Fedora はいったいどうしちゃったのだ…
標準の壁紙がダサい、今まで文句の付けようがないものばかりだったのに。
初めてデフォルト以外を使うことにした、ってコレはどうでもいいか。

とりあえず致命的な問題は無さそうである。
ということで Fedora 18 が入っていた旧 HDD からデータのコピー。
で困った。

今まで旧 HDD をシリアル ATA のスレーブに接続して普通にコピペしていた。
同様に接続して起動すると当然 Fedora 19 が立ち上がるがパスワードで弾かれる。
まさかと思って Fedora 18 のパスワードを入力したら立ち上がった、何だコレ???

しかも新旧のホームディレクトリが合体、ワケガワカラナイヨ。
試しに接続のマスターとスレーブを逆にしてみたら丸々逆になっただけ。
多分前回から変わったインストーラがそうなるようにしているのだろうけど。

とにかくこれじゃコピペできないよ、勘弁してよ。
一旦外付け HDD を経由、みたいにするしかなさそうです。

とりあえず最小限コピーをやってアプリ導入。

google-chrome の rpm を落す。
W クリックでインストールできるかな?
依存関係で wget と redhat-lsb が必要なはず。

おぉ今回は依存関係をダウンロードもしてくれるようだ。
でも肝心のインストールは失敗、コマンドならインストールできた。

sudo yum install google-chrome-s[残りは Tab キーで保管]

あぁいつもの Fedora だ。

先月の終わりくらいから SELinux に引っ掛るようになったけど同じだった。
SELinux ポリシーを変更するかもう少し様子見するかで迷う。

ところで Opera は Linux 用を新規で作るのをヤメてしまったんだね。
お金にならないのだろうし chrome エンジンでは選ぶ理由が無いしまあね。
会社苦しいんだろうな…

rpm-fusion は相変わらず GUI セットアップがうまくいかない。
Fedora 14 to the most current:
以下のコマンドを端末にコピペ、もう毎回すぎて慣れた。

で、音楽や動画のデコーダーは Totem への動画ドロップだけで以前同様に導入できた。
何故か一つ動画ファイルをドロップだけで手持ちメディアが全部再生できるようになった。
まとめてインストールになったのかな?

sylpheed, ghex, keepassx

えっと他に何かあったかな。

あと他に気が付いたことは、、、

起動時のマウスカーソル位置が左上から右下に変わっている。
勝手にアクティビティ画面にならなくなって少し嬉しい。

サスペンドが凄い、一瞬でオフになる。
一応書くと[電源オフ]メニューを出した状態で Alt キーね。

続く。