Xul: panel position on multiple monitors

I have a xul: panel on my Firefox extension. I provide the position to display according to screen.width and screen.height. My problem occurs when I have several monitors, and I launch the browser on the first monitor, it appears on the second, and the xul panel: is drawn in accordance with the first screen resolution on the second. Is there a solution for painting in accordance with the second screen resolution?

+2
source share
1 answer

Background:

When I was developing a mutli-monitor application based on XULRunner to work, I found that you simply could not predict where the window manager will place the windows launched after the first launch of your main application / browser window.

XULRunner correctly gave me:

  • geometry (width, height) for full screen display
  • window position for this window on a display with multiple monitors
  • Window status (MAXIMIZED, MINIMIZED, none) for this window
  • the ability to (not) maximize the window

He didn’t really respect the geometry of several monitors when I set a set of window coordinates that would place the window on a specific monitor (rather, the window manager placed a new window wherever he liked).

This left me with the task of somehow doing the following:

  • The location of the window relative to the display with multiple monitors and
    (since moving the window sometimes lost window focus)
  • Window focusing.

I managed to achieve both using an external DLL loaded / used by js-ctypes.


Example for Win32:

The following are the basics for linking an external DLL to JavaScript. This example only applies to Win32, but I also did it for Linux and for MacOSX (which were simpler and more complicated than Win32).

There are 3 parts:

  1. Preferred JavaScript code for loading / binding Win32 API
  2. CPP header file for our external dll
  3. Source CPP file for our external dll

I create a simple GUI DLL project with the later two files and compile wmctrl.dll , depending on msvcr100.dll , and use Dependency Walker to find the "plain C" characters exported by the DLL for using js-ctypes.

I also created a JavaScript library around the APIs that allowed me to manipulate, track, and maintain the window state / geometry for multiple windows over several application launches, but this has little to do with this simple example.

In privileged JavaScript code:

 // 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); } 
+2
source

Source: https://habr.com/ru/post/1447307/


All Articles