2012-04-09 22 views
2

我在我的Firefox擴展上有一個xul:面板。我給出了根據screen.width和screen.height顯示的位置。當我有多個顯示器時,出現問題,我在第一個顯示器上啓動瀏覽器,它出現在第二個顯示器上,根據第一個顯示器的第二個分辨率繪製xul:面板。根據第二個屏幕的分辨率是否有解決方案?xul:在多個顯示器上的面板位置

+0

這是一個血腥的混亂,居然!我不得不暫停開發基於XULRunner的應用程序,以開展窗口管理。我直接從'js-ctypes'使用Win32或X11 apis(取決於平臺)。基本上,我會很快改變一個窗口的標題,以便通過窗口枚舉從C++代碼中識別它,然後將其設置回原始標題並保留對已識別窗口的引用,以便以後通過'js暴露給JavaScript的API使用-ctypes'。 – 2012-04-09 08:32:28

+0

不確定XULJet是否有任何改進,或者其中任何一項適用於Firefox擴展。 – 2012-04-09 08:35:34

+0

我會寫一個答案,但也許有人可以用一個純JavaScript解決方案:-) – 2012-04-09 08:40:49

回答

2

背景:

當我開發基於XULRunner的工作一座耗資監視器應用程序,我發現你根本無法預測在窗口管理器將放置首次推出後,推出的Windows您主應用程序/瀏覽器窗口。

的XULRunner沒有正確地給我:

  • 幾何形狀(寬度,高度)爲完整的多監視器顯示
  • 窗口位置的多監視器顯示器上
  • 窗口狀態(MAXIMIZED給定窗口,MINIMIZED ,兩者都不是)爲給定的窗口
  • 能力(未)最大化窗口

它沒有正確的尊重,當我specifi多顯示器幾何編輯一組窗口座標,這些窗口座標可以將窗口放置在特定的監視器上(而不是窗口管理器將窗口放在任何它喜歡的地方)。

這讓我莫名其妙地做任務如下:

  • 定位相對於多顯示器顯示的窗口,
    (因爲移動窗口有時會失去窗口焦點)
  • 聚焦窗口。

我能夠在js-ctypes加載/使用的外部DLL的幫助下實現兩者。

爲Win32

例子:

這裏的是外部DLL結合JavaScript的基礎知識。這個例子只涵蓋了Win32,但我也爲Linux和MacOSX做了這個(與Win32相比,它們更容易分別更難&)。

分爲3個部分:

  1. 特權JavaScript代碼來加載/結合的Win32 API
  2. 我們外部DLL的CPP頭文件
  3. 我們外部DLL的CPP源文件

我構建了一個簡單的GUI DLL項目,其後兩個文件&編譯爲wmctrl.dll,具體取決於msvcr100.dll,並且使用Dependency Walker來查找由此導出的「plain C」符號由js-ctypes使用的DLL。

我還內置了JavaScript庫周圍允許操作,跟蹤&持續多個窗口在應用程序的多個窗口運行狀態/幾何形狀的API,但是,這並不是這個簡單的例子確實有關。

在特權的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("[email protected]@[email protected]", 
    ctypes.stdcall_abi, ctypes.uint32_t, 
    ctypes.char.ptr); 

// wmctrl_window_focus: takes unsigned 32bit (long) "window handle". 
var window_focus = lib.declare("[email protected]@[email protected]", 
    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("[email protected]@[email protected]", 
    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); 
}