flypig.co.uk

List items

Items from the current list are shown below.

Gecko

20 Dec 2023 : Day 113 #
It's a new dawn, it's a new day. As I write this the sun is peaking up over the horizon casting all the clouds orange against the pastel blue sky, trees silhouetted against the skyline. It feels like a good day to start moving forwards with this and implementing "hidden windows" in the sailfish-browser code.
 
Trees silhouetted against an orange-blue sunrise

Thankfully I've nearly returned to full health again and as I write this am feeling a lot better. Everyone has been so generous with their kind wishes, it's made a real difference. Wherever you are in the world, I hope you're in good health, and if not I hope your recovery is swift and full!

I'm also very excited about the fact my talk on all this gecko development has been accepted for presentation at FOSDEM in the FOSS on Mobile devroom! If you're planning to be in Brussels yourself on the 3-4 February I really hope to see you there.

I'm just about to get on to starting coding when I notice a notification icon on my Matrix client. It seems emilio has got back to me. Yesterday I asked on the Mozilla Matrix "Printing" channel whether I'd need to implement some "window hiding" feature in the front-end to handle these empty print windows. Here's the reply.
 
Well instead of a window you can create a browser like this: https://searchfox.org/mozilla-central/search?q=symbol:%23handleStaticCloneCreatedForPrint

It's a brief but pithy answer. Digging through the links provided, a few things spring to mind:
  1. The handleStaticCloneCreatedForPrint() method in printUtils.js doesn't exist in ESR 91. Maybe I'll have to create it?
  2. Nor does the createParentBrowserForStaticClone() method in the same file; I'll probably have to back port that too.
  3. The OPEN_PRINT_BROWSER case in browser.js exists in browser.js in ESR 91, but I'm not sure whether it's getting executed. I should check.
  4. I'm wondering if, in order to go down this route, I'd need to call startPrintWindow() in printUtils.js to initiate a print, rather than the CanonicalBrowserContext::print() method I'm currently using.
Lots of questions. The first thing to check is whether the OPEN_PRINT_BROWSER execution path is being taken at all in my current build. As this is JavaScript code I can't use the debugger to find out; I'll need to put some debug print statements into the code instead.

As I dig around in the code I quickly come to realise that browser.js isn't a file that's used by sailfish-browser. I guess this functionality is largely handled by the front-end QML code instead. However the printUtils.js file is there in omni.ja so I can still add some debug output to that.
  /**  
   * Initialize a print, this will open the tab modal UI if it is enabled or
   * defer to the native dialog/silent print.
   *
   * @param aBrowsingContext
   *        The BrowsingContext of the window to print.
   *        Note that the browsing context could belong to a subframe of the
   *        tab that called window.print, or similar shenanigans.
   * @param aOptions
   *        {openWindowInfo}      Non-null if this call comes from window.print().
   *                              This is the nsIOpenWindowInfo object that has to
   *                              be passed down to createBrowser in order for the
   *                              child process to clone into it.
   *        {printSelectionOnly}  Whether to print only the active selection of
   *                              the given browsing context.
   *        {printFrameOnly}      Whether to print the selected frame.
   */
  startPrintWindow(aBrowsingContext, aOptions) {
    dump("PRINT: startPrintWindow\n");
[...]

  /**  
   * Starts the process of printing the contents of a window.
   *
   * @param aBrowsingContext
   *        The BrowsingContext of the window to print.
   * @param {Object?} aPrintSettings
   *        Optional print settings for the print operation
   */
  printWindow(aBrowsingContext, aPrintSettings) {
    dump("PRINT: printWindow\n");
[...]
I pack up these changes into omni.ja, run the browser and set the print running. There's plenty of debug output, but neither of these new entries show up.

So the next step is to switch out the call to CanonicalBrowserContext::print() to a call to startPrintWindow() if that's possible.

Doing this directly doesn't give good results, for multiple reasons. First we get an error stating that MozElements isn't defined. That's coming from the definition of PrintPreview in the PrintUtils.js file:
class PrintPreview extends MozElements.BaseControl {
[...]
The definition of MozElements happens in customElements.js and should be a global within the context of a chrome window. As the text at the top of the file explains: "This is loaded into chrome windows with the subscript loader.". For the time being I can work around this by calling PrintUtils.printWindow() instead of PrintUtils.startPrintWindow() because the former doesn't make use of the preview window.

However, when I do this the script complains that document is undefined, caused by this condition in printWindow():
    const printPreviewIsOpen = !!document.getElementById(
      "print-preview-toolbar"
    );
Again, I can work around this by setting printPreviewIsOpen to false and commenting out these lines. Having made these two changes, the print works but opens a window, just as before.

Looking more carefully through the ESR 91 code and the code that emilio mentioned, it looks to me like this is the critical part (although I'm not in the least bit certain about this):
    if (openWindowInfo) {
      let printPreview = new PrintPreview({
        sourceBrowsingContext: aBrowsingContext,
        openWindowInfo,
      });
      let browser = printPreview.createPreviewBrowser("source");
      document.documentElement.append(browser);
      // Legacy print dialog or silent printing, the content process will print
      // in this <browser>.
      return browser;
    }
This will create the preview window which will be used for the silent printing. But even this doesn't seem to be doing what we need: it's still creating the browser window.

The fact that neither document nor MozElements is defined makes me think that this needs to be called from inside a chrome window for this to work. And I don't know how to do that.

I've come full circle again. I've sent a message to emilio for clarification, but I'm yet again brought back to the thought that I'm going to need to hide this window manually, whether it's the print preview browser, or a tab that's opened to hold the cloned document in.

I feel like I've been chasing my tail yet again. I need some positive thoughts: tomorrow I plan to be back to full health and doing some actual coding.

If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.

Comments

Uncover Disqus comments