Cygwinでcygwin1.dllフリーなWindows実行ファイルを作る (MinGW-w64)

Cygwingcc ver.3.xでは-mno-cygwinオプションを付ければcygwin1.dllのリンクされない実行ファイルを作る事ができるが、最近のgcc (ver.4.x系列?)ではこのオプションは使えない。

$ gcc -mno-cygwin sample.c
gcc: The -mno-cygwin flag has been removed; use a mingw-targeted cross-compiler.
$ gcc --version
gcc (GCC) 4.5.3
(以下略)

代わりにMinGW-w64gccを使えば良い。*1 *2
Cygwin Setupで以下のパッケージをインストール。

  • 64ビット環境なら
  • 32ビット環境なら

これでインストールされたgccを使えばOK。-mno-cygwinオプションは不要。

$ x86_64-w64-mingw32-gcc sample.c

ちなみにインストールしたパッケージに含まれる実行ファイルを調べるには以下のコマンドを使うといい。

$ cygcheck -l mingw64-x86_64-gcc-core | grep exe

参考

*1:名前にw64とあるが32ビット環境向けのも提供している

*2:MinGW-w64はMinGWからスピンオフしたプロジェクト

タスク切り替えソフトcltc ver. 0.8.9.2用64ビット対応パッチ

[追記: 2017-11-04] 開発停止したcltcを騙し騙し使うよりも、ちゃんと開発継続してるソフト使うのがお勧めです。同じような操作感でより高機能な Tascher -Task Switcher- を今は使っています。


コマンドライン型タスク切り替えソフトcltcが64ビットOS上でもちゃんと動くようにするパッチ作りました。ver. 0.8.9.2用です。Windows Vista以降用です。

これで64ビットアプリもちゃんと絞り込めるようになります。

https://wlt.dip.jp/~wlt/cltc_64bit_app_patch.exe

上記URLからパッチ適用プログラムを落として、cltc.exeのあるフォルダで実行すればOKです。

変更内容

GetModuleFileNameEx関数の代わりにQueryFullProcessImageName関数を使うようにしました。

64ビット上の32ビットアプリではGetModuleFileNameEx関数で64ビットアプリのファイルパスを取得できなかったからです。(そもそもその前に呼んでるEnumProcessModules関数も同様で、こいつがエラー吐いてGetModuleFileNameEx関数は呼び出されてなかった。)

Greasemonkey 0.9.5でもldrize_cooperationがちょっと動くようにする

Greasemonkey 0.9.5から*1内部仕様変更の為に2011年6月9日現在のldrize_cooperation.jsが動かなくなったので、復活させるパッチを書いた。ただし、ldrize_cooperation.jsの他の色々な機能は死んだまま(拡張ヒントlとLとか、コマンドmbとかpinとか、intelligence_bindとかも)*2

まずFirefox 4以降の人はFirefox 4 で Minibuffer + LDRize + ReblogCommand を動かす | WWW WATCHを参考にLDRize自体を動くようにしておく。

あとは2011年6月9日現在のldrize_cooperation.jsへ以下のパッチを当てるだけ。

--- a/ldrize_cooperation.js
+++ b/ldrize_cooperation.js
@@ -315,7 +315,8 @@
             this.LDRizeCooperationPanel.setAttribute("src",value ? DISABLE_ICON : ENABLE_ICON);
             _isEnable = value;
         },
-        isEnableLDRize: function() this.LDRize.getSiteinfo() != undefined,
+        isEnableLDRize: function() this.LDRize.getSiteinfo() != undefined ||
+                                   window.content.wrappedJSObject.document.getElementById("gm_ldrize") != null,
         isEnableLDRizeCooperation: function() /^https?:$/.test(content.location.protocol) && this.isEnable && this.isEnableLDRize(),

         //Pin

パッチ当て済みのldrize_cooperation.jsはこちら

動かなくなった原因

ldrize_cooperation.jsは、今までLDRizeとMinibufferのインスタンスを取得するために、GM_GreasemonkeyService#evalInSandbox()と言う関数をフックしていた。けれど例のグリモンのコミット0cb7d4acf437a4a88e3dによって、このGM_GreasemonkeyService#evalInSandbox()に相当する関数が、グリモンのコンポーネントグローバルな関数runScriptInSandbox()に置き換えられ、フックできなくなったためLDRize、Minibufferのインスタンスを取得できなくなった。*3
つまり、パッチを見て感じ取れる通り、isEnableLDRize()関数がfalseを返しちゃうのが割と直接の原因。

解決方法

LDRizeはページ内に"gm_ldrize"と言うIDを持ったDIV要素を挿入するので、それがあればisEnableLDRize()がtrueを返すようにした。これだけ。

所でそもそもLDRizeインスタンス取得できてないのにLDRizeできているのは不思議に思うかもしれない。実はldrize_cooperation.jsはLDRizeの普通の操作にそのインスタンスを利用するのではなく、単純にページドキュメントへキーイベントを発行することでLDRizeしていたからでした。

*1:正確には0cb7d4acf437a4a88e3dから

*2:intelligence_bindは前から死んでた?

*3:コンポーネント周りの知識が足りてないので変な事言ってるかもしれません。

Vimperatorでステータスバーのパネル(アイコン)をクリックするコマンドのプラグイン

アドオンなどによって追加されるステータスバーのパネル(アイコン)をクリックするためのVimperatorプラグインを書いた。
https://github.com/vimpr/vimperator-plugins/blob/master/statusbar_panel.js

補完で選べるようにしてあるし簡単に使えると思う。

例えばグリモンのアイコンを右クリックしたい時は

:statusbarpanel -button=r gm-status

とやればおk。

コマンド書式

:statusbarpanel [-b[utton]={l | m | r}] [-d[ouble-click]] {panel-id}


最低限、パネルのidを指定する。これは上図のように補完で一覧が出るのでそこから選べば良い。
オプションの-buttonでクリックする(マウスの)ボタンの種類を選べる。

l 左ボタン(デフォルト)
m 中ボタン(スクロールボタン)
r 右ボタン

-double-clickオプションを付けるとダブルクリックになる。
-buttonオプションは-bと省略できる。
-double-clickオプションは-dと省略できる。

Firefox 4のステータスバー

Firefox 4ではステータスバーは削除され、アドオンバーに置き換えられた。ただし後方互換性を確保するため、ステータスバーはアドオンバーに内包されている。https://dev.mozilla.jp/2010/11/making-add-on-compatible-firefox-4/

Vimperatorもff17a1cf26あたりのコミットから

:set toolbars=addons

でアドオンバーを表示できるようになっている。
詳しくははてなグループへ。

Vimperatorも6fb2547652のコミットから

:set guioptions+=A

でアドオンバーを表示できるようになっている。
guioptions=Aは短い命だったね。

おまけ

実は、指定するidはステータスバーパネル以外のものでも良く、XULウィンドウの任意のノードのidを与えることができる。
例えばホームを開くボタンをクリックしたい時は

:statusbarpanel home-button

とする。idはDOM Inspectorで調べられる。


・・・あれ?これちゃんと汎用的なコマンドとしてリリースすべきだったかな・・・。:clickxulとか。
でも、ステータスバーパネルをクリックしたくて作ったので、とりあえず分かりやすいこの形式でリリース。

Limechatのチャンネルログに現れるURLをキーボードだけで開くスクリプト

Limechatのチャンネルログに現れるURLを開くのにマウスへ手を伸ばすのが面倒くさいので、コマンドで開けるようにするスクリプト書いた。
使い方は簡単。入力欄に

/u 2

と書いてエンターすれば、チャンネルログの下から2番目のURLが開く。
特徴

  • 数字を省略した場合は1とみなす。
  • 同一発言中に複数のURLが現れる場合は、左のものほど若い数字に対応する。
  • 一つのチャンネルログ内で指定できる最大値は10(スクリプト内の変数MAXで指定可能)
  • URLは日本語が混じっててもOK(複数のURLは半角スペースか全角スペース、半角カンマ、全角カンマで区切られてる必要がある。(※かなり雑な正規表現でURLを抽出してます)URLエンコーディングは多分ブラウザ次第)

2011/02/03: LimechatはカンマもURLに含めて認識するのでそれに合わせた変更した。あと念のため正規表現エスケープシーケンス使うようにした

スクリプトの内容はこんな感じ。
https://gist.github.com/815658

Firefox 4.0b10でGreasemonkey 0.9.1のユーザスクリプトのwindowを共通にする改造(開発者orVimper向け)

2010/02/09追記: Firefox 4.0b11でもおk
2010/03/01追記: Firefox 4.0b12でもおk。のようだけど、時々うまく動かない事も
2010/03/14追記: Firefox 4.0 RC1でもおk

2012/01/04追記: Greasemonkey 0.9.13で動かなくなってます。てかバグってグリモン動かなくなるのでこれを適用しないでください


LDRizeが使えないのは耐えられないので、Firefox 4.0b10でGreasemonkey 0.9.1のユーザスクリプトのwindowを共通にする改造をグリモンに施した。
LDRizeが使えないことについてはこの辺参照。

あとTombloo使ってる場合はこちらの方法がいいかも
Twitter / @utatane: GMのWindowをsharedにするTombloo ... http://twitter.com/#!/Constellation/statuses/31786122715594752

改造方法

グリモンのソースはここ https://github.com/greasemonkey/greasemonkey
改造パッチはこんな感じ

--- a/components/greasemonkey.js
+++ b/components/greasemonkey.js
@@ -255,6 +255,9 @@ GM_GreasemonkeyService.prototype = {
     var xmlhttpRequester;
     var resources;
     var unsafeContentWin = wrappedContentWin.wrappedJSObject;
+    var sharedWindow = {};
+    sharedWindow.window = sharedWindow;
+    sharedWindow.__proto__ = new XPCNativeWrapper(unsafeContentWin);

     // detect and grab reference to firebug console and context, if it exists
     var firebugConsole = this.getFirebugConsole(unsafeContentWin, chromeWin);
@@ -297,6 +300,7 @@ GM_GreasemonkeyService.prototype = {
                                                 "registerMenuCommand",
                                                 unsafeContentWin);

+      sandbox.window = sharedWindow;
       // Re-wrap the window before assigning it to the sandbox.__proto__
       // This is a workaround for a bug in which the Security Manager
       // vetoes the use of eval.

サンドボックスから見えるwindowを、content Windowをプロトタイプにした普通のオブジェクトにしたて、これをユーザスクリプト間で使い回すわけです。

Firefox 4.0b10ではこれで動いてくれるけど、何故かFirefox 3.6.13では動かない
何故かsharedWindow.window.documentがundefined。多分3.6.13のXPCNativeWrapperあたりのバグだと思う。3.6.13ではGM 0.9.0使えばいいか。

まぁ、とりあえず、こんな方法でどうでしょう?


2010/02/01 追記

Vimperatorユーザなら簡単にLDRizeできるようになるよ

そういえばGMXPCOMで上記の部分取り出していじれるから、グリモンのソースコードいじってxpiビルドする必要なかった。
Vimperならvimperatorrcに以下を追加するだけで上記パッチあてられる

" Greasemonkey 0.9.1でwindowを共通にする。(必要性は一時的?"
js <<EOM
autocommands.add('VimperatorEnter', '.*',
  function() {
    let gm = Components.classes['@greasemonkey.mozdev.org/greasemonkey-service;1'];
    if (gm) {
      gm = gm.getService().wrappedJSObject;
      if (gm.injectScripts.toSource().search('sharedWindow') == -1) {
          gm.injectScripts = liberator.eval(
              gm.injectScripts.toSource()
                  .replace(/(?=var firebugConsole)/,
                          'var sharedWindow = {};' +
                          'sharedWindow.window = sharedWindow;' +
                          'sharedWindow.__proto__ = new XPCNativeWrapper(unsafeContentWin);')
                  .replace(/(?=sandbox\.__proto__)/, ' sandbox.window = sharedWindow;'),
              gm.injectScripts);
      }
    }
  });
EOM

あとLDRize使うVimperならldrize_cooperation.js使ってると思うので、上記GMの改造にあわせて次のパッチが必要です
すでに以下のパッチは最新版に取り込まれました。最新のldrize_cooperation.jsを使えばおkです。swirhenさんありがとうございます

https://github.com/vimpr/vimperator-plugins/blob/master/ldrize_cooperation.jshttps://github.com/vimpr/vimperator-plugins/blob/master/ldrize_cooperation.js

--- a/ldrize_cooperation.js
+++ b/ldrize_cooperation.js
@@ -184,18 +184,18 @@
                     } else {
                         var [code,codebase,sandbox] = arguments;
                     }
-                    if(sandbox.LDRize != undefined && sandbox.Minibuffer != undefined){
+                    if(sandbox.window.LDRize != undefined && sandbox.window.Minibuffer != undefined){
                         sandbox.window.addEventListener("focus",function(){
-                            self.LDRize = liberator.eval("self",sandbox.LDRize.getSiteinfo);
-                            self.Minibuffer = liberator.eval("command",sandbox.Minibuffer.addCommand);
-                            if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.LDRize;
-                            if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.Minibuffer.command;
+                            self.LDRize = liberator.eval("self",sandbox.window.LDRize.getSiteinfo);
+                            self.Minibuffer = liberator.eval("command",sandbox.window.Minibuffer.addCommand);
+                            if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.window.LDRize;
+                            if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.window.Minibuffer.command;
                         },false);
-                        if(window.content.wrappedJSObject == sandbox.unsafeWindow){
-                            self.LDRize = liberator.eval("self",sandbox.LDRize.getSiteinfo);
-                            self.Minibuffer = liberator.eval("command",sandbox.Minibuffer.addCommand);
-                            if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.LDRize;
-                            if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.Minibuffer.command;
+                        if(window.content.wrappedJSObject == sandbox.window.unsafeWindow){
+                            self.LDRize = liberator.eval("self",sandbox.window.LDRize.getSiteinfo);
+                            self.Minibuffer = liberator.eval("command",sandbox.window.Minibuffer.addCommand);
+                            if (typeof self.LDRize.getSiteinfo != 'function') self.LDRize = sandbox.window.LDRize;
+                            if (typeof self.Minibuffer.addCommand != 'function') self.Minibuffer = sandbox.window.Minibuffer.command;
                         }
                     }
                 });

GMの改造にあわせて、sandboxのところをsandbox.windowにした。

Vimperatorで現在のタブの右隣にタブを開くようにする(外部アプリからURLを開く時なども)

2012/07/27 Firefox Nightly 17.0aで動かなくなってたので修正
2011/03/14 Firefox 4 RCから動かなくなってたので修正



TabMixPlusとかのアドオンに頼らずに、Vimperatorで現在のタブの右隣にタブを開くようにする。この方法なら:tabopenコマンドに限らず、外部アプリからURLを開く時でも新しいタブで開くようになる。

これはabout:configのbrowser.tabs.insertRelatedAfterCurrentがtrueで無ければならない。

VimpでなくFirefox自体の機能に手を入れるので、他のアドオンなどと干渉する可能性もあるので注意。

vimperatorrcファイルに次を追加(なお、先日書いた記事「Vimperatorの:tabopenコマンド(liberator.open)で現在のタブのすぐ右隣にタブを開くようにする - wltの日記」の設定は不要になる。)。

" Firefoxのタブを開く位置をデフォで現在のタブの右隣にする(※ gBrowser.addTabの改造)"
js <<EOM
gBrowser.addTab = liberator.eval(
    '(' +
    gBrowser.addTab.toSource()
            .replace(/var\s*aRelatedToCurrent;/, 'var aRelatedToCurrent = true;')
            .replace(/aRelatedToCurrent\s*=\s*params\.relatedToCurrent;/, 'aRelatedToCurrent = params.relatedToCurrent === undefined ? true : params.relatedToCurrent;') +
    ')',
    gBrowser.addTab);
EOM