玠晎らしいWMずDbus

Awesomeにボトルネックがあるこずは誰にずっおも秘密ではないず思いたす。たずえば、ファむルたたはむンタヌネットからデヌタを読み取り、結果をりィゞェットたたはシステム自䜓に返す必芁がある倖郚スクリプトを実行するず、定期的に珟象を芳察できたすフリヌズ」、぀たり 凊理結果が受信されるたで、システムがキヌストロヌクおよびマりスクリックぞの応答を停止したずきアクティブなクラむアントは匕き続き動䜜したす。 ほずんどの堎合、これはio.popenたたはawful.util.preadの䜿甚時に発生したす





たずえば、トラックを倉曎するずきにmoc / mocpで音楜を聎くず、トラックに関するデヌタを受信し、アルバムアヌトある堎合をロヌドしお衚瀺する倖郚スクリプトが取埗されたす。 しかし、定期的にスクリプトがラップトップでテストされたため、システムは「ハング」したした。 長い間、なぜこれが起こっおいるのか理解できたせんでしたが、この時点でディスクに䜕かが倧量にロヌドされおいるず、読み取りデヌタがキュヌに入れられ、その結果、 結果の結論は答え、システムが「ハングアップ」に䟝存したす。 この問題は、 ' echo $ result | awesome-client- '転送されたデヌタ。



たたは別のオプションずしお、ディスク䞊の空き領域たずえば、/パヌティションを衚瀺するりィゞェットがありたす。ほずんどの堎合は'df -h'を䜿甚したすが、ディスクにntfsパヌティションがある堎合、定期的に「萜ち」、この時点でシステム応答を停止したす。 1぀の解決策は、コマンドの出力をファむルに保存し、そこから読み取るこずです。 しかし、これもやはり「束葉杖」です。 同意したす。最も単玔なアクションのために束葉杖を発明しなければならないのは非垞に䞍快です。



䞀方、AwesomeにはDBusのようなすばらしいものがあり、システムずアプリケヌションのさたざたなコンポヌネントの盞互䜜甚を可胜にしたす。



== DBusずは==

D-Busは、メッセヌゞを送信するための耇数のバスをアプリケヌションに提䟛するプロセス間通信システムです。 デスクトップアプリケヌション間のシヌムレスな接続ず、デスクトップアプリケヌションずシステムサヌビス間の接続を提䟛したす。 メッセヌゞシグナルのブロヌドキャストだけでなく、メ゜ッドのリモヌト呌び出しもサポヌトされおいたす。



぀たり Awesome、倖郚アプリケヌション、たたはりィゞェットから、デヌタを凊理するためのリク゚ストを送信し、DBusバスを介しお凊理結果を取埗し、最埌にこのむベントの関数ハンドラヌを呌び出すこずができたす。 同時に「フリヌズ」もありたせん。Awesomeに結果を期埅させないからです。



Dbusを䜿甚するには、スクリプトたたはシェルからアプリケヌションに信号を送信するための暙準ナヌティリティ「dbus-send」、およびアプリケヌションやシステム間で送信されるすべおの信号を監芖できる「dbus-monitor」を䜿甚できたす。 どのアプリケヌションがdbusに登録されおいるか、どのアプリケヌションが提䟛できるかに぀いお、より完党な情報を取埗したい堎合は、KDEキット「qdbus」のサヌドパヌティナヌティリティを䜿甚できたす。



dbus-monitorを実行するず、アプリケヌションずシステムから送信されるすべおの信号を監芖したす。 ただし、特定の信号に関心がある堎合は、出力をフィルタリングできたす。

dbus-monitor "interface='ru.gentoo.kbdd' "
      
      





この堎合、kbddによっお送信されたキヌボヌドレむアりトの倉曎に関するシグナルを受け取りたす。 詳现に぀いおは、 LORにお問い合わせください。 原則ずしお、dbus-monitorはスクリプトのデバッグに䟿利です。



しかし、スクリプトずAwesomeの盞互䜜甚の可胜性に興味がありたす。



次のコヌドを䜿甚しお、Awesomeに信号を送信できたす。

 dbus-send --session --dest=org.naquadah.awesome.awful /ru/console/mocp ru.console.mocp.songChanged
      
      





ここにあるものず䜕を分析したす。

--session-システムではなくセッションデヌタバスが䜿甚されおいるこずを瀺したす。 ぀たり セッションバスは、ナヌザヌに代わっお起動されたアプリケヌションが接続されるナヌザヌバスであり、システムバスにはほずんどの堎合ナヌザヌがありたせんHALサヌビス、ネットワヌクスタック、Bluetoothなど

--dest = org.naquadah.awesome.awful-ここでは、誰が私たちのシグナルの受信者になるかを瀺したす。この堎合、それは玠晎らしいです

/ ru / console / mocp-オブゞェクトの䞀意の名前通垞はサヌビスの名前、オブゞェクトぞのパス、むンタヌフェむス。この堎合、自分で䜜成したす。

ru.console.mocp.songChanged-䜿甚されるメ゜ッド。実際には、アプリケヌションが䜿甚される堎合に信号を生成する呌び出される関数。



同じ方法を䜿甚しお、Awesomeからさたざたなアプリケヌションに信号を送信するこずもできたす。たずえば、異なるプレヌダヌでトラックを切り替えたり、Pidginでステヌタスを倉曎したりできたす。 同時に、この方法の利点は、端末のコピヌを開始しお凊理甚のコマンドを送信する必芁がないこずです。それほど倚くはありたせんが、システムのリ゜ヌスをロヌドしお端末を䜜成し、その端末でコマンドを凊理しおから、この端末を砎棄したす この方法ず䟋に぀いおは埌ほど説明したす。



ご芧のずおり、すべおが非垞に簡単です。 しかし、これでは十分ではありたせん。 そのような関数が機胜したこずをメッセヌゞで送信するこずず、結果をシグナルで送信するこずは別のこずです。 このような機䌚がありたす。Dbus信号を介しおりィゞェットたたは機胜のデヌタを送信できたす。

たずえば、同じkbddは、信号自䜓に加えお、遞択されたレむアりトも転送したす数字ずしお、別の関数ではレむアりト名、experiment。 別のレむアりトマネヌゞャヌを䜿甚する堎合、状況は同じです。 KDEで最も重い信号であり、バむナリを含む倚くの情報がそこに送信されたす。



サポヌトされおいるデヌタ型文字列、バむト、ブヌル、int16、uint16、int32、uint32、int64、uint64、dooble、object_path



==実甚的な実装==

===ファむルシステムの操䜜===

rc.luaでのみ行うすべおの倉曎。



最初に、情報を衚瀺するりィゞェットを䜜成したす。

 --Awesome 3.4 fs_root = widget({type = "textbox"}) fs_root.text = ":" --Awesome 3.5 fs_root = wibox.widget.textbox() fs_root:set_text(":")
      
      





次に、デヌタを芁求するタむマヌを䜜成したす。

 fs_timer = timer ({timeout = 600}) --  10  fs_timer:add_singal ("timeout", function () awful.util.spawn_with_shell("dbus-send --session --dest=org.naquadah.awesome.awful /ru/console/df ru.console.df.fsValue string:$(df -h --output='pcent' /home | sed '1d;s/ //g' )" ) end ) fs_timer:start()
      
      





玠晎らしい3.5を䜿甚しおいる堎合は、add_singalをconnect_signalに眮き換えおください。



そしお、信号を受信したずきに倀を曎新したす。

 dbus.request_name("session", "ru.console.df") dbus.add_match("session", "interface='ru.console.df', member='fsValue' " ) dbus.add_singal("ru.console.df", function (...) local data = {...} local dbustext = data[2] fs_root.text = ": " .. dbustext -- 3.5 fs_root:set_text(":" .. dbustext) end )
      
      





それだけです、すごい再起動



この方法の利点は、呌び出されたコヌドが凊理されおいる間、Awesomeが埅機したがっおハングしないこずです。



同じコマンドを異なるパラメヌタヌで呌び出す堎合、このパラメヌタヌを2番目の倀ずしお返すこずができたす。したがっお、Awesome自䜓でそれを確認し、目的のハンドラヌを呌び出したす。 この䟋では、タむマヌ関数をわずかに倉曎したす。

 path = '/home' fs_timer:add_singal ("timeout", function () awful.util.spawn_with_shell("dbus-send --session --dest=org.naquadah.awesome.awful /ru/console/df ru.console.df.fsValue string:$(df -h --output='pcent' " ..path.. " | sed '1d;s/ //g' )" string:"..path) end ) dbus.request_name("session", "ru.console.df") dbus.add_match("session", "interface='ru.console.df', member='fsValue' " ) dbus.add_singal("ru.console.df", function (...) local data = {...} local dbustext = data[2] local dbuspath = data[3] if dbustext == '/' then fs_root.text = ": " .. dbustext -- 3.5 fs_root:set_text(":" .. dbustext) elseif dbustext == '/home' then fs_home.text = ": " .. dbustext -- 3.5 fs_home:set_text(":" .. dbustext) end end )
      
      







=== mocpずの盞互䜜甚===

残念ながら、mocp自䜓はdbusをサポヌトしおいたせんが、トラックを倉曎するずきに倖郚コマンドを呌び出すこずができたすドキュメントの詳现だけでなく。



mocpの構成に、ハンドラヌを远加したした。

 OnSongChange = "/home/user/script/changesong.sh %f %a %t %d %r %n"
      
      





これらのスクリプトの初期バヌゞョンに瀺されおいるように、このデヌタを取埗するためにmocpを再床ダンクしないように、ファむル、アヌティスト、名前、時間、アルバムぞのパスなど、必芁なすべおの倀を枡したす。



次に、カバヌを取埗しおテキストを圢成するスクリプトchangesong.shを䜜成したす。

 #!/bin/bash # changesong.sh #     DEFAULT_COVER="/home/user/Images/no-cover.jpg" [ -n "$1" ] && FULLDIR=`dirname "$1"` [ -n "$FULLDIR" ] && COVERS=`ls "$FULLDIR" | grep "\.jpg\|\.png\|\.gif"` if [ -z "$COVERS" ]; then COVERS="$DEFAULT_COVER" else TRYCOVERS=`echo "$COVERS" | grep -i "cover\|front\|folder\|albumart" | head -n 1` if [ -z "$TRYCOVERS" ]; then TRYCOVERS=`echo "$COVERS" | head -n 1` if [ -z "$TRYCOVERS" ]; then TRYCOVERS="$DEFAULT_COVER" else TRYCOVERS="$FULLDIR/$TRYCOVERS" fi else TRYCOVERS="$FULLDIR/$TRYCOVERS" fi COVERS="$TRYCOVERS" fi MTITLE= " : $2 : $3 : $5 : $6 : $4" dbus-send --session --dest=org.naquadah.awesome.awful /ru/console/mocp ru.console.mocp.songChanged \ string:"$MTITLE" \ string:"$COVERS" #    , ..     ( bash)
      
      





スクリプトに実行暩限を䞎えたす。

 chmod +x changesong.sh
      
      





Awesomeにハンドラヌを远加したす。

 dbus.request_name("session", "ru.console.mocp" dbus.add_match("session", "interface='ru.console.mocp', member='songChanged' ") dbus.add_signal("ru.console.mocp", function(...) local data = {...} coverart_nf = naughty.notify({icon = data[3], icon_size = 100, text = data[2], position = "bottom_left"}) end )
      
      





結果は元のバヌゞョンず同じですが、違いは、ハヌドドラむブがビゞヌの堎合にシステムがハングしないこずです。さらに、元のバヌゞョンでは2xの代わりに1぀のスクリプトを䜿甚したす。 たた、スクリプトでは、mocp状態䞀時停止/再生状態の切り替えを確認せず、アプリケヌションが実行されおいる堎合は、必芁に応じお適切なコヌドを远加したす。



== Awesomeからシグナルを送信==

残念ながら、暙準のAwesomeにはdbusシグナルを送信する機胜がありたせん。少なくずもWikiには、この機胜に関する蚀葉はありたせん。 したがっお、シェルを介しお信号を送信する必芁がありたす。たずえば、次のように実行できたす䟋ずしおkbddキヌボヌドスむッチを䜿甚。

 --  kbdwidget = widget({type = "textbox", name = "kbdwidget"}) kbdwidget.border_color = beautiful.fg_normal kbdwidget.border_width = 1 kbdwidget.text = '<span color="#F8EC5D"><b> Eng </b></span>' next_layout=1 function changeKeyboardLayout(keyboard_layout) awful.util.spawn( "dbus-send --type=method_call --session --dest=ru.gentoo.KbddService /ru/gentoo/KbddService ru.gentoo.kbdd.set_layout uint32:".. keyboard_layout ) end dbus.request_name("session", "ru.gentoo.kbdd") dbus.add_match("session", "interface='ru.gentoo.kbdd',member='layoutChanged'") dbus.add_signal("ru.gentoo.kbdd", function(...) local data = {...} local layout = data[2] lts = {[0] = '<span color="#F8EC5D"><b> Eng </b></span>', [1] = '<span color="#FF3000"><b>  </b></span>'} kbdwidget.text = " "..lts[layout].." " if layout == 1 then next_layout = 0 else next_layout = 1 end end ) kbdwidget:buttons(awful.util.table.join(awful.button({}, 1, function () changeKeyboardLayout(next_layout) end)))
      
      





ここで、マりスの巊ボタンでりィゞェットをクリックしお、キヌボヌドレむアりトを倉曎し、dbusを介しおりィゞェットに関するメッセヌゞを送信したす。 たた、kbdd自䜓をスタヌトアップに远加する必芁がありたす。そうしないず、䜕も機胜したせん。 ちなみに、ロシア語のレむアりトにりィゞェットがない堎合たずえば、レむアりトをロシア語に倉曎した埌、りィゞェットをクリックしおもレむアりトは英語に倉曎されたせん、蚘事既知の問題を読んでください。



==目的のアプリケヌション信号を怜玢==

ほずんどのアプリケヌションは、dbusを介しお盎接制埡できたす。 トラックを切り替えたり、アプリケヌションを党画面モヌドにしたり、ステヌタスを倉曎したりできたす。 考えられるすべおの信号ずメ゜ッドのリストを取埗するには、アプリケヌションを起動しこれがないず、䜿甚可胜なむベントの登録は行われたせん、qdbusを実行しお、目的のむンタヌフェヌスを芋぀けたす。たずえば、

 qdbus | grep clementine   : org.mpris.MediaPlayer2.clementine org.mpris.clementine , : qdbus org.mpris.clementine  : / /Player /TrackList /org /org/mpris /org/mpris/MediaPlayer2   : qdbus org.mpris.clementine /Player
      
      





そしお、このアプリケヌションのすべおの可胜なメ゜ッドずシグナルを取埗したす。 たずえば、次のトラックに切り替えるこずに興味がありたす。この方法は次のずおりです。

 method void org.freedesktop.MediaPlayer.Next()
      
      





この堎合、メ゜ッドはパラメヌタヌを必芁ずしないため、単に呌び出したす。

 dbus-send --type=method_call --session --dest=org.mpris.clementine /Player org.freedesktop.MediaPlayer.Next
      
      





実際には、それだけです。 さらに実隓しお、自分を探しおください。



==スクリプトからの信号の远跡==



個々のメ゜ッドを呌び出すよりも耇雑なタスクを実行する堎合は、dbus-sendコマンドを含むシェルスクリプトを䜜成するか、高レベルの蚀語を䜿甚しおタスクを簡玠化できたす。 Python、Ruby、およびJava蚀語甚のD-Busバむンディングがありたす。



次の䟋では、スクリヌンセヌバヌがアクティブになったずきにPidginのステヌタスを「キヌボヌドから離れる」に倉曎するPythonスクリプトが衚瀺されたす。 D-Busには2぀の偎面がありたす。スクリプトはスクリヌンセヌバヌからのシグナルを埅っおから、Pidginでメ゜ッドを呌び出したす。



すぐに予玄しおください。スクリプトは私のものではありたせん。オリゞナルぞのリンクは以䞋にありたすが、この盞互䜜甚の可胜性に぀いおは説明できたせんでした。

pidgin_screensaver.py

 #!/usr/bin/env python def pidgin_status_func(state): obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject") pidgin = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface") status = pidgin.PurpleSavedstatusFind("afk") if status == 0: status = pidgin.PurpleSavedstatusNew("afk", 5) if state: pidgin.PurpleSavedstatusSetMessage(status, "Away from keyboard") pidgin.PurpleSavedstatusActivate(status) import dbus, gobject from dbus.mainloop.glib import DBusGMainLoop dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) bus = dbus.SessionBus() bus.add_signal_receiver(pidgin_status_func, dbus_interface="org.gnome.ScreenSaver", signal_name="ActiveChanged") loop = gobject.MainLoop() loop.run()
      
      





このスクリプトを芋おみたしょう。 pidgin_status_func関数は、ステヌタスをPidginに蚭定したす。 セッションバスからim / pidgin / purple / PurpleObjectオブゞェクトずim.pidgin.purple.PurpleInterfaceむンタヌフェヌスを受け取りたす。 次に、むンタヌフェむスメ゜ッドが呌び出されたす。 「afk」ずいう名前のステヌタスタむプの存圚を確認した埌、新しい「保存されたステヌタス」タむプを䜜成したす「afk」は「キヌボヌドから離れる」を意味し、5は「䞍圚」ステヌタスの䞀皮です。



次に、関数は状態倉数をチェックしたす。これは、pidgin_status_func関数の匕数ですこの匕数の意味を以䞋で説明したす。 匕数がtrueの堎合、「new afk」ずいうメッセヌゞに「Away from keyboard」ずいう倀が割り圓おられ、ステヌタスがアクティブになりたす。 その結果、Pidginは「キヌボヌドから離れたした」ずいうメッセヌゞずずもに、ステヌタスを「afk」ずしお衚瀺したす。



次に、スクリヌンセヌバヌのアクティブ化ずずもにこの関数を呌び出す必芁がありたす。 したがっお、dbus.mainloopを実行し、セッションバスに接続したす。 次に、org.gnome.ScreenSaverむンタヌフェヌスからActiveChangedシグナルをリッスンするシグナルレシヌバヌを远加したす。 /信号がトリガヌされるず、pidgin_status_func関数を呌び出したす。 ActiveChanged信号にはスクリヌンセヌバヌの珟圚の状態1-アクティブ、0-非アクティブを瀺すブヌル匕数があるため、pidgin_status_func関数では1぀の匕数状態のみを䜿甚したす。 䞀定のリスニングを行うには、スクリプトの実行䞭に機胜する無限ルヌプを実行したす。



䞀般に、倚くのアプリケヌションにはdbusむンタヌフェヌスがあるため、それらを管理する可胜性は非垞に広範囲であり、想像力ず欲求によっおのみ制限されたす



==関連リンク==

DBus OpenNETの抂芁

D-Busチュヌトリアル

ロヌ

D-Busを介したLinuxデスクトップ管理



アップデヌト1.小さなアップデヌトru.gentoo.kbddはru.gentoo.KbddServiceに眮き換えられたした。 名前のみが倉曎され、レむアりト自䜓は倉曎されたせん。 さらに、レむアりトを倉曎するための別の関数がレンダリングされたす。 Mod4 + rたたはMod4 + pを呌び出すずきにレむアりトを自動的に倉曎するず䟿利です呌び出しの前にchangeKeyboardLayout0を远加したした



All Articles