Changeset 159042 in webkit


Ignore:
Timestamp:
Nov 11, 2013 12:30:06 AM (10 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK] Crash when printing via javascript in WebKit2
https://bugs.webkit.org/show_bug.cgi?id=124043

Reviewed by Martin Robinson.

It happens because the print operation when started by the
WebProcess due to a DOM operation is supposed to be synchronous
and our print operation is always asynchronous. This is currently
handled only in the UI process because other ports print
synchronously in the WebProcess. In the GTK+ port we need to
notify the WebProcess that the print operation should run
synchronously when request by a DOM operation. Together with the
print settings and page setup we now send a print mode that can be
sync or async. When printing in sync mode we run a nested main loop
for the print operation, making sure that print sources have a
higher priority.

  • Shared/PrintInfo.cpp:

(WebKit::PrintInfo::encode): Encode the print mode.
(WebKit::PrintInfo::decode): Decode the print mode.

  • Shared/PrintInfo.h: Add PrintMode enum.
  • Shared/gtk/PrintInfoGtk.cpp:

(WebKit::PrintInfo::PrintInfo): Initialize print mode.

  • UIProcess/API/gtk/WebKitPrintOperation.cpp:

(drawPagesForPrintingCompleted): Do not call endPrinting() when
printing synchronously because WebPageProxy already calls it right
after sending the message to the WebProcess.
(webkitPrintOperationPrintPagesForFrame): Create the PrintInfo
struct with a print mode.
(webkitPrintOperationSetPrintMode): Helper private function to set
the print mode of the print operation.

  • UIProcess/API/gtk/WebKitPrintOperationPrivate.h:
  • UIProcess/API/gtk/WebKitWebView.cpp:

(webkitWebViewPrintFrame): Set sync print mode when printing due
to a UIClient request.

  • WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp:

(WebKit::PrintPagesData::PrintPagesData): Create a main loop when
printing synchronously.
(WebKit::WebPrintOperationGtk::WebPrintOperationGtk): Initialize
print mode.
(WebKit::WebPrintOperationGtk::printPagesIdleDone): Finish the
nested main loop when printing synchronously.
(WebKit::WebPrintOperationGtk::print): Run a nested main loop when
printing synchronously.

  • WebProcess/WebPage/gtk/WebPrintOperationGtk.h:

(WebKit::WebPrintOperationGtk::printMode): Return the print mode.

Location:
trunk/Source/WebKit2
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r159041 r159042  
     12013-11-11  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Crash when printing via javascript in WebKit2
     4        https://bugs.webkit.org/show_bug.cgi?id=124043
     5
     6        Reviewed by Martin Robinson.
     7
     8        It happens because the print operation when started by the
     9        WebProcess due to a DOM operation is supposed to be synchronous
     10        and our print operation is always asynchronous. This is currently
     11        handled only in the UI process because other ports print
     12        synchronously in the WebProcess. In the GTK+ port we need to
     13        notify the WebProcess that the print operation should run
     14        synchronously when request by a DOM operation. Together with the
     15        print settings and page setup we now send a print mode that can be
     16        sync or async. When printing in sync mode we run a nested main loop
     17        for the print operation, making sure that print sources have a
     18        higher priority.
     19
     20        * Shared/PrintInfo.cpp:
     21        (WebKit::PrintInfo::encode): Encode the print mode.
     22        (WebKit::PrintInfo::decode): Decode the print mode.
     23        * Shared/PrintInfo.h: Add PrintMode enum.
     24        * Shared/gtk/PrintInfoGtk.cpp:
     25        (WebKit::PrintInfo::PrintInfo): Initialize print mode.
     26        * UIProcess/API/gtk/WebKitPrintOperation.cpp:
     27        (drawPagesForPrintingCompleted): Do not call endPrinting() when
     28        printing synchronously because WebPageProxy already calls it right
     29        after sending the message to the WebProcess.
     30        (webkitPrintOperationPrintPagesForFrame): Create the PrintInfo
     31        struct with a print mode.
     32        (webkitPrintOperationSetPrintMode): Helper private function to set
     33        the print mode of the print operation.
     34        * UIProcess/API/gtk/WebKitPrintOperationPrivate.h:
     35        * UIProcess/API/gtk/WebKitWebView.cpp:
     36        (webkitWebViewPrintFrame): Set sync print mode when printing due
     37        to a UIClient request.
     38        * WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp:
     39        (WebKit::PrintPagesData::PrintPagesData): Create a main loop when
     40        printing synchronously.
     41        (WebKit::WebPrintOperationGtk::WebPrintOperationGtk): Initialize
     42        print mode.
     43        (WebKit::WebPrintOperationGtk::printPagesIdleDone): Finish the
     44        nested main loop when printing synchronously.
     45        (WebKit::WebPrintOperationGtk::print): Run a nested main loop when
     46        printing synchronously.
     47        * WebProcess/WebPage/gtk/WebPrintOperationGtk.h:
     48        (WebKit::WebPrintOperationGtk::printMode): Return the print mode.
     49
    1502013-11-10  Carlos Garcia Campos  <cgarcia@igalia.com>
    251
  • trunk/Source/WebKit2/Shared/PrintInfo.cpp

    r141619 r159042  
    5353    CoreIPC::encode(encoder, printSettings.get());
    5454    CoreIPC::encode(encoder, pageSetup.get());
     55    encoder.encodeEnum(printMode);
    5556#endif
    5657}
     
    7071    if (!CoreIPC::decode(decoder, info.pageSetup))
    7172        return false;
     73    if (!decoder.decodeEnum(info.printMode))
     74        return false;
    7275#endif
    7376
  • trunk/Source/WebKit2/Shared/PrintInfo.h

    r143499 r159042  
    4848    PrintInfo();
    4949#if PLATFORM(GTK)
    50     explicit PrintInfo(GtkPrintSettings*, GtkPageSetup*);
     50    enum PrintMode {
     51        PrintModeAsync,
     52        PrintModeSync
     53    };
     54
     55    explicit PrintInfo(GtkPrintSettings*, GtkPageSetup*, PrintMode = PrintModeAsync);
    5156#else
    5257    explicit PrintInfo(NSPrintInfo *);
     
    6065    GRefPtr<GtkPrintSettings> printSettings;
    6166    GRefPtr<GtkPageSetup> pageSetup;
     67    PrintMode printMode;
    6268#endif
    6369
  • trunk/Source/WebKit2/Shared/gtk/PrintInfoGtk.cpp

    r106102 r159042  
    3131namespace WebKit {
    3232
    33 PrintInfo::PrintInfo(GtkPrintSettings* settings, GtkPageSetup* pageSetup)
     33PrintInfo::PrintInfo(GtkPrintSettings* settings, GtkPageSetup* pageSetup, PrintMode printMode)
    3434    : pageSetupScaleFactor(gtk_print_settings_get_scale(settings) / 100.0)
    3535    , availablePaperWidth(gtk_page_setup_get_paper_width(pageSetup, GTK_UNIT_POINTS) - gtk_page_setup_get_left_margin(pageSetup, GTK_UNIT_POINTS) - gtk_page_setup_get_right_margin(pageSetup, GTK_UNIT_POINTS))
     
    3737    , printSettings(settings)
    3838    , pageSetup(pageSetup)
     39    , printMode(printMode)
    3940{
    4041    ASSERT(settings);
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp

    r159041 r159042  
    2121#include "WebKitPrintOperation.h"
    2222
    23 #include "PrintInfo.h"
    2423#include "WebKitPrintOperationPrivate.h"
    2524#include "WebKitPrivate.h"
     
    7473    WebKitWebView* webView;
    7574    gulong webViewDestroyedId;
     75    PrintInfo::PrintMode printMode;
    7676
    7777    GRefPtr<GtkPrintSettings> printSettings;
     
    265265    GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(WEBKIT_PRINT_OPERATION(context));
    266266    WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView));
    267     page->endPrinting();
     267
     268    // When running synchronously WebPageProxy::printFrame() calls endPrinting().
     269    if (printOperation->priv->printMode == PrintInfo::PrintModeAsync)
     270        page->endPrinting();
    268271
    269272    const WebCore::ResourceError& resourceError = toImpl(wkPrintError)->platformError();
     
    279282static void webkitPrintOperationPrintPagesForFrame(WebKitPrintOperation* printOperation, WebFrameProxy* webFrame, GtkPrintSettings* printSettings, GtkPageSetup* pageSetup)
    280283{
    281     PrintInfo printInfo(printSettings, pageSetup);
     284    PrintInfo printInfo(printSettings, pageSetup, printOperation->priv->printMode);
    282285    WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView));
    283286    page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted));
     
    299302    webkitPrintOperationPrintPagesForFrame(printOperation, webFrame, priv->printSettings.get(), priv->pageSetup.get());
    300303    return response;
     304}
     305
     306void webkitPrintOperationSetPrintMode(WebKitPrintOperation* printOperation, PrintInfo::PrintMode printMode)
     307{
     308    printOperation->priv->printMode = printMode;
    301309}
    302310
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperationPrivate.h

    r108069 r159042  
    2121#define WebKitPrintOperationPrivate_h
    2222
     23#include "PrintInfo.h"
    2324#include "WebFrameProxy.h"
    2425#include "WebKitPrintOperation.h"
    2526
    2627WebKitPrintOperationResponse webkitPrintOperationRunDialogForFrame(WebKitPrintOperation*, GtkWindow* parent, WebKit::WebFrameProxy*);
     28void webkitPrintOperationSetPrintMode(WebKitPrintOperation*, WebKit::PrintInfo::PrintMode);
    2729
    2830#endif // WebKitPrintOperationPrivate_h
  • trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp

    r158437 r159042  
    16841684        return;
    16851685
     1686    webkitPrintOperationSetPrintMode(printOperation.get(), PrintInfo::PrintModeSync);
    16861687    WebKitPrintOperationResponse response = webkitPrintOperationRunDialogForFrame(printOperation.get(), 0, frame);
    16871688    if (response == WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL)
  • trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp

    r130509 r159042  
    110110        m_callbackID = callbackID;
    111111        gtk_enumerate_printers(reinterpret_cast<GtkPrinterFunc>(enumeratePrintersFunction), this,
    112                                reinterpret_cast<GDestroyNotify>(enumeratePrintersFinished), FALSE);
     112            reinterpret_cast<GDestroyNotify>(enumeratePrintersFinished), m_printMode == PrintInfo::PrintModeSync);
    113113    }
    114114
     
    218218        , isValid(true)
    219219    {
     220        if (printOperation->printMode() == PrintInfo::PrintModeSync)
     221            mainLoop = adoptGRef(g_main_loop_new(0, FALSE));
     222
    220223        if (printOperation->collateCopies()) {
    221224            collatedCopies = printOperation->copies();
     
    359362
    360363    RefPtr<WebPrintOperationGtk> printOperation;
     364    GRefPtr<GMainLoop> mainLoop;
    361365
    362366    int totalPrinted;
     
    393397    , m_printSettings(printInfo.printSettings.get())
    394398    , m_pageSetup(printInfo.pageSetup.get())
     399    , m_printMode(printInfo.printMode)
    395400    , m_printContext(0)
    396401    , m_callbackID(0)
     
    670675{
    671676    PrintPagesData* data = static_cast<PrintPagesData*>(userData);
     677    if (data->mainLoop)
     678        g_main_loop_quit(data->mainLoop.get());
    672679
    673680    data->printOperation->printPagesDone();
     
    706713    m_yDPI = yDPI;
    707714    m_cairoContext = adoptRef(cairo_create(surface));
    708     m_printPagesIdleId = gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE + 10, printPagesIdle,
    709                                                    data.leakPtr(), printPagesIdleDone);
    710 }
    711 
    712 }
     715
     716    // Make sure the print pages idle has more priority than IPC messages comming from
     717    // the IO thread, so that the EndPrinting message is always handled once the print
     718    // operation has finished. See https://bugs.webkit.org/show_bug.cgi?id=122801.
     719    unsigned idlePriority = m_printMode == PrintInfo::PrintModeSync ? G_PRIORITY_DEFAULT - 10 : G_PRIORITY_DEFAULT_IDLE + 10;
     720    GMainLoop* mainLoop = data->mainLoop.get();
     721    m_printPagesIdleId = gdk_threads_add_idle_full(idlePriority, printPagesIdle, data.leakPtr(), printPagesIdleDone);
     722    if (m_printMode == PrintInfo::PrintModeSync) {
     723        ASSERT(mainLoop);
     724        g_main_loop_run(mainLoop);
     725    }
     726}
     727
     728}
  • trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h

    r130028 r159042  
    5454    GtkPrintSettings* printSettings() const { return m_printSettings.get(); }
    5555    GtkPageSetup* pageSetup() const { return m_pageSetup.get(); }
     56    PrintInfo::PrintMode printMode() const { return m_printMode; }
    5657    void setNumberOfPagesToPrint(size_t numberOfPages) { m_numberOfPagesToPrint = numberOfPages; }
    5758    unsigned int pagesToPrint() const { return m_pagesToPrint; }
     
    9697    GRefPtr<GtkPrintSettings> m_printSettings;
    9798    GRefPtr<GtkPageSetup> m_pageSetup;
     99    PrintInfo::PrintMode m_printMode;
    98100    WebCore::PrintContext* m_printContext;
    99101    uint64_t m_callbackID;
Note: See TracChangeset for help on using the changeset viewer.