Firefox拡張機能にxul:panelがあります。screen.widthとscreen.heightに従って表示する位置を指定します。複数のモニターがあり、最初のモニターでブラウザーを起動すると、問題が発生します。2番目のモニターに表示され、2番目のモニターの最初の画面の解像度に従ってxul:panelが描画されます。2番目の画面の解像度に従って描画するための解決策はありますか?
1 に答える
バックグラウンド:
XULRunnerをベースにしたマルチモニターアプリケーションを仕事用に開発していたとき、メインアプリケーション/ブラウザーウィンドウの最初の起動後にウィンドウマネージャーが起動したウィンドウを配置する場所を予測できないことがわかりました。
XULRunnerは私に正しく与えました:
- フルマルチモニターディスプレイのジオメトリ(幅、高さ)
- マルチモニターディスプレイ上の特定のウィンドウのウィンドウ位置
- 指定されたウィンドウのウィンドウ状態(MAXIMIZED、MINIMIZED、どちらでもない)
- ウィンドウを(非)最大化する機能
特定のモニターにウィンドウを配置するウィンドウ座標のセットを指定した場合、マルチモニターのジオメトリが正しく尊重されませんでした(ウィンドウマネージャーは、新しいウィンドウを好きな場所に配置しました)。
それはどういうわけか次のことをする仕事を私に残しました:
- マルチモニターディスプレイに対するウィンドウの配置、および
(ウィンドウを移動するとウィンドウのフォーカスが失われることがあるため) - ウィンドウに焦点を合わせます。
js-ctypesによってロード/使用される外部DLLの助けを借りて両方を達成することができました。
Win32の例:
外部DLLをJavaScriptにバインドするための基本は次のとおりです。この例ではWin32のみを取り上げていますが、LinuxとMacOSX(Win32と比較してそれぞれ簡単で難しい)でもこれを行いました。
3つの部分があります:
- Win32APIをロード/バインドするための特権JavaScriptコード
- 外部DLLのCPPヘッダーファイル
- 外部DLLのCPPソースファイル
wmctrl.dll
に応じて、後の2つのファイルとコンパイルmsvcr100.dll
を使用して単純なGUI DLLプロジェクトを構築し、Dependency Walkerを使用して、js-ctypesで使用するためにDLLによってエクスポートされた「プレーンC」シンボルを見つけました。
また、APIを中心にJavaScriptライブラリを構築しました。これにより、アプリケーションの複数の実行にわたって複数のウィンドウのウィンドウの状態/ジオメトリを操作、追跡、および永続化できますが、これはこの単純な例にはあまり関係ありません。
特権JavaScriptコードの場合:
// get js-ctypes, you do this part a bit differently from browser chrome
const {Cc,Ci,Cu} = require("chrome");
var file=null, lib=null, ctypes = {};
Cu.import("resource://gre/modules/ctypes.jsm", ctypes);
var ctypes = ctypes.ctypes;
// build platform specific library path
var filename = ctypes.libraryName("wmctrl");
var comp = "@mozilla.org/file/directory_service;1";
var file = Cc[comp].getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
file.append("browser_code");
file.append(filename);
// get the JavaScript library interface (load the library)
var lib = ctypes.open(file.path);
// wmctrl_find_window: returing unsigned 32bit (long) "window handle"
// takes string "window title".
var find_window = lib.declare("?wmctrl_find_window@@YAKPAD@Z",
ctypes.stdcall_abi, ctypes.uint32_t,
ctypes.char.ptr);
// wmctrl_window_focus: takes unsigned 32bit (long) "window handle".
var window_focus = lib.declare("?wmctrl_window_focus@@YAXK@Z",
ctypes.stdcall_abi, ctypes.void_t,
ctypes.uint32_t);
// wmctrl_window_move: takes unsigned 32bit (long) "window handle",
// and two (x & y) signed 32bit ints.
var window_move = lib.declare("?wmctrl_window_move@@YAXKHH@Z",
ctypes.stdcall_abi, ctypes.void_t,
ctypes.uint32_t, ctypes.int32_t, ctypes.int32_t);
wmctrldll.h
#ifdef WMCTRLDLL_EXPORTS
#define WMCTRLDLL_API __declspec(dllexport)
#else
#define WMCTRLDLL_API __declspec(dllimport)
#endif
WMCTRLDLL_API void wmctrl_window_focus (unsigned long wid);
WMCTRLDLL_API void wmctrl_window_move (unsigned long wid, int x, int y);
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title);
wmctrldll.cpp
#include "stdafx.h"
#include "wmctrldll.h"
typedef struct {
HWND hWnd;
char title[255];
} myWinSpec;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) {
char String[255];
myWinSpec* to_find = (myWinSpec*) lParam;
// not a window
if (!hWnd) return TRUE;
// not visible
if (!IsWindowVisible(hWnd)) return TRUE;
// no window title
if (!GetWindowTextA(hWnd, (LPSTR)String, 255)) return TRUE;
// no title match
if (strcmp(String, to_find->title) != 0) return TRUE;
to_find->hWnd = hWnd;
return FALSE;
}
WMCTRLDLL_API void wmctrl_window_focus(unsigned long wid) {
SetForegroundWindow((HWND) wid);
}
WMCTRLDLL_API unsigned long wmctrl_find_window(char* find_title) {
myWinSpec to_find;
sprintf_s(to_find.title, sizeof(to_find.title), "%s", find_title);
to_find.hWnd = 0;
EnumWindows(EnumWindowsProc, (LPARAM)&to_find);
return (unsigned long) to_find.hWnd;
}
WMCTRLDLL_API void wmctrl_window_move(unsigned long wid, int x, int y) {
UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE;
SetForegroundWindow((HWND) wid);
SetWindowPos((HWND) wid, HWND_NOTOPMOST, x, y, NULL, NULL, flags);
}