From c30a6232df03e1efbd9f3b226777b07e087a1122 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 12 Oct 2020 14:27:29 +0200 Subject: BASELINE: Update Chromium to 85.0.4183.140 Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen --- chromium/ui/gtk/BUILD.gn | 10 +- chromium/ui/gtk/gtk_ui.cc | 6 +- chromium/ui/gtk/print_dialog_gtk.cc | 541 ------------------------ chromium/ui/gtk/print_dialog_gtk.h | 92 ----- chromium/ui/gtk/printing/OWNERS | 3 + chromium/ui/gtk/printing/print_dialog_gtk.cc | 551 +++++++++++++++++++++++++ chromium/ui/gtk/printing/print_dialog_gtk.h | 89 ++++ chromium/ui/gtk/printing/printing_gtk_util.cc | 96 +++++ chromium/ui/gtk/printing/printing_gtk_util.h | 27 ++ chromium/ui/gtk/printing_gtk_util.cc | 96 ----- chromium/ui/gtk/printing_gtk_util.h | 27 -- chromium/ui/gtk/select_file_dialog_impl_kde.cc | 73 ++-- chromium/ui/gtk/x/gtk_event_loop_x11.cc | 47 ++- chromium/ui/gtk/x/gtk_ui_delegate_x11.cc | 9 +- 14 files changed, 849 insertions(+), 818 deletions(-) delete mode 100644 chromium/ui/gtk/print_dialog_gtk.cc delete mode 100644 chromium/ui/gtk/print_dialog_gtk.h create mode 100644 chromium/ui/gtk/printing/OWNERS create mode 100644 chromium/ui/gtk/printing/print_dialog_gtk.cc create mode 100644 chromium/ui/gtk/printing/print_dialog_gtk.h create mode 100644 chromium/ui/gtk/printing/printing_gtk_util.cc create mode 100644 chromium/ui/gtk/printing/printing_gtk_util.h delete mode 100644 chromium/ui/gtk/printing_gtk_util.cc delete mode 100644 chromium/ui/gtk/printing_gtk_util.h (limited to 'chromium/ui/gtk') diff --git a/chromium/ui/gtk/BUILD.gn b/chromium/ui/gtk/BUILD.gn index 99d97e9c145..02e12b9db88 100644 --- a/chromium/ui/gtk/BUILD.gn +++ b/chromium/ui/gtk/BUILD.gn @@ -35,10 +35,10 @@ jumbo_component("gtk") { "native_theme_gtk.h", "nav_button_provider_gtk.cc", "nav_button_provider_gtk.h", - "print_dialog_gtk.cc", - "print_dialog_gtk.h", - "printing_gtk_util.cc", - "printing_gtk_util.h", + "printing/print_dialog_gtk.cc", + "printing/print_dialog_gtk.h", + "printing/printing_gtk_util.cc", + "printing/printing_gtk_util.h", "select_file_dialog_impl.cc", "select_file_dialog_impl.h", "select_file_dialog_impl_gtk.cc", @@ -76,6 +76,7 @@ jumbo_component("gtk") { "//ui/aura", "//ui/base", "//ui/base:buildflags", + "//ui/base/cursor:theme_manager", "//ui/base/ime", "//ui/base/ime/linux", "//ui/display", @@ -85,7 +86,6 @@ jumbo_component("gtk") { "//ui/gfx", "//ui/gfx:native_widget_types", "//ui/gfx/geometry", - "//ui/gfx/x", "//ui/native_theme", "//ui/shell_dialogs", "//ui/strings", diff --git a/chromium/ui/gtk/gtk_ui.cc b/chromium/ui/gtk/gtk_ui.cc index 77d2c7633af..69d7afecc3a 100644 --- a/chromium/ui/gtk/gtk_ui.cc +++ b/chromium/ui/gtk/gtk_ui.cc @@ -29,7 +29,7 @@ #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkShader.h" -#include "ui/base/cursor/cursor_theme_manager_linux_observer.h" +#include "ui/base/cursor/cursor_theme_manager_observer.h" #include "ui/base/ime/linux/fake_input_method_context.h" #include "ui/base/ime/linux/linux_input_method_context.h" #include "ui/base/ime/linux/linux_input_method_context_factory.h" @@ -51,8 +51,8 @@ #include "ui/gtk/input_method_context_impl_gtk.h" #include "ui/gtk/native_theme_gtk.h" #include "ui/gtk/nav_button_provider_gtk.h" -#include "ui/gtk/print_dialog_gtk.h" -#include "ui/gtk/printing_gtk_util.h" +#include "ui/gtk/printing/print_dialog_gtk.h" +#include "ui/gtk/printing/printing_gtk_util.h" #include "ui/gtk/select_file_dialog_impl.h" #include "ui/gtk/settings_provider_gtk.h" #include "ui/native_theme/native_theme.h" diff --git a/chromium/ui/gtk/print_dialog_gtk.cc b/chromium/ui/gtk/print_dialog_gtk.cc deleted file mode 100644 index 7368b297a54..00000000000 --- a/chromium/ui/gtk/print_dialog_gtk.cc +++ /dev/null @@ -1,541 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gtk/print_dialog_gtk.h" - -#include - -#include -#include -#include -#include -#include -#include - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/no_destructor.h" -#include "base/sequence_checker.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task/post_task.h" -#include "base/task/thread_pool.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/values.h" -#include "printing/metafile.h" -#include "printing/print_job_constants.h" -#include "printing/print_settings.h" -#include "ui/aura/window.h" -#include "ui/gtk/gtk_ui.h" -#include "ui/gtk/gtk_ui_delegate.h" -#include "ui/gtk/gtk_util.h" -#include "ui/gtk/printing_gtk_util.h" - -#if defined(USE_CUPS) -#include "printing/mojom/print.mojom.h" -#endif - -using printing::PageRanges; -using printing::PrintSettings; - -namespace { - -#if defined(USE_CUPS) -// CUPS Duplex attribute and values. -const char kCUPSDuplex[] = "cups-Duplex"; -const char kDuplexNone[] = "None"; -const char kDuplexTumble[] = "DuplexTumble"; -const char kDuplexNoTumble[] = "DuplexNoTumble"; -#endif - -constexpr int kPaperSizeTresholdMicrons = 100; -constexpr int kMicronsInMm = 1000; - -// Checks whether |gtk_paper_size| can be used to represent user selected media. -// In fuzzy match mode checks that paper sizes are "close enough" (less than -// 1mm difference). In the exact mode, looks for the paper with the same PPD -// name and "close enough" size. -bool PaperSizeMatch(GtkPaperSize* gtk_paper_size, - const PrintSettings::RequestedMedia& media, - bool fuzzy_match) { - if (!gtk_paper_size) - return false; - - gfx::Size paper_size_microns( - static_cast(gtk_paper_size_get_width(gtk_paper_size, GTK_UNIT_MM) * - kMicronsInMm + - 0.5), - static_cast(gtk_paper_size_get_height(gtk_paper_size, GTK_UNIT_MM) * - kMicronsInMm + - 0.5)); - int diff = std::max( - std::abs(paper_size_microns.width() - media.size_microns.width()), - std::abs(paper_size_microns.height() - media.size_microns.height())); - bool close_enough = diff <= kPaperSizeTresholdMicrons; - if (fuzzy_match) - return close_enough; - - return close_enough && !media.vendor_id.empty() && - media.vendor_id == gtk_paper_size_get_ppd_name(gtk_paper_size); -} - -// Looks up a paper size matching (in terms of PaperSizeMatch) the user selected -// media in the paper size list reported by GTK. Returns nullptr if there's no -// match found. -GtkPaperSize* FindPaperSizeMatch(GList* gtk_paper_sizes, - const PrintSettings::RequestedMedia& media) { - GtkPaperSize* first_fuzzy_match = nullptr; - for (GList* p = gtk_paper_sizes; p && p->data; p = g_list_next(p)) { - GtkPaperSize* gtk_paper_size = static_cast(p->data); - if (PaperSizeMatch(gtk_paper_size, media, false)) - return gtk_paper_size; - - if (!first_fuzzy_match && PaperSizeMatch(gtk_paper_size, media, true)) - first_fuzzy_match = gtk_paper_size; - } - return first_fuzzy_match; -} - -class StickyPrintSettingGtk { - public: - StickyPrintSettingGtk() : last_used_settings_(gtk_print_settings_new()) {} - ~StickyPrintSettingGtk() { - NOTREACHED(); // Intended to be used with base::NoDestructor. - } - - GtkPrintSettings* settings() { return last_used_settings_; } - - void SetLastUsedSettings(GtkPrintSettings* settings) { - DCHECK(last_used_settings_); - g_object_unref(last_used_settings_); - last_used_settings_ = gtk_print_settings_copy(settings); - } - - private: - GtkPrintSettings* last_used_settings_; - - DISALLOW_COPY_AND_ASSIGN(StickyPrintSettingGtk); -}; - -StickyPrintSettingGtk& GetLastUsedSettings() { - static base::NoDestructor settings; - return *settings; -} - -// Helper class to track GTK printers. -class GtkPrinterList { - public: - GtkPrinterList() { gtk_enumerate_printers(SetPrinter, this, nullptr, TRUE); } - - ~GtkPrinterList() { - for (GtkPrinter* printer : printers_) - g_object_unref(printer); - } - - // Can return nullptr if there's no default printer. E.g. Printer on a laptop - // is "home_printer", but the laptop is at work. - GtkPrinter* default_printer() { return default_printer_; } - - // Can return nullptr if the printer cannot be found due to: - // - Printer list out of sync with printer dialog UI. - // - Querying for non-existant printers like 'Print to PDF'. - GtkPrinter* GetPrinterWithName(const std::string& name) { - if (name.empty()) - return nullptr; - - for (GtkPrinter* printer : printers_) { - if (gtk_printer_get_name(printer) == name) - return printer; - } - - return nullptr; - } - - private: - // Callback function used by gtk_enumerate_printers() to get all printer. - static gboolean SetPrinter(GtkPrinter* printer, gpointer data) { - GtkPrinterList* printer_list = reinterpret_cast(data); - if (gtk_printer_is_default(printer)) - printer_list->default_printer_ = printer; - - g_object_ref(printer); - printer_list->printers_.push_back(printer); - - return FALSE; - } - - std::vector printers_; - GtkPrinter* default_printer_ = nullptr; -}; - -} // namespace - -// static -printing::PrintDialogGtkInterface* PrintDialogGtk::CreatePrintDialog( - PrintingContextLinux* context) { - return new PrintDialogGtk(context); -} - -PrintDialogGtk::PrintDialogGtk(PrintingContextLinux* context) - : base::RefCountedDeleteOnSequence( - base::SequencedTaskRunnerHandle::Get()), - context_(context) {} - -PrintDialogGtk::~PrintDialogGtk() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (dialog_) { - aura::Window* parent = gtk::GetAuraTransientParent(dialog_); - if (parent) { - parent->RemoveObserver(this); - gtk::ClearAuraTransientParent(dialog_); - } - gtk_widget_destroy(dialog_); - dialog_ = nullptr; - } - if (gtk_settings_) { - g_object_unref(gtk_settings_); - gtk_settings_ = nullptr; - } - if (page_setup_) { - g_object_unref(page_setup_); - page_setup_ = nullptr; - } - if (printer_) { - g_object_unref(printer_); - printer_ = nullptr; - } -} - -void PrintDialogGtk::UseDefaultSettings() { - DCHECK(!page_setup_); - DCHECK(!printer_); - - // |gtk_settings_| is a new copy. - gtk_settings_ = gtk_print_settings_copy(GetLastUsedSettings().settings()); - page_setup_ = gtk_page_setup_new(); - - InitPrintSettings(std::make_unique()); -} - -void PrintDialogGtk::UpdateSettings( - std::unique_ptr settings) { - if (!gtk_settings_) - gtk_settings_ = gtk_print_settings_copy(GetLastUsedSettings().settings()); - - auto printer_list = std::make_unique(); - printer_ = printer_list->GetPrinterWithName( - base::UTF16ToUTF8(settings->device_name())); - if (printer_) { - g_object_ref(printer_); - gtk_print_settings_set_printer(gtk_settings_, - gtk_printer_get_name(printer_)); - if (!page_setup_) { - page_setup_ = gtk_printer_get_default_page_size(printer_); - } - } - - gtk_print_settings_set_n_copies(gtk_settings_, settings->copies()); - gtk_print_settings_set_collate(gtk_settings_, settings->collate()); - -#if defined(USE_CUPS) - std::string color_value; - std::string color_setting_name; - printing::GetColorModelForMode(settings->color(), &color_setting_name, - &color_value); - gtk_print_settings_set(gtk_settings_, color_setting_name.c_str(), - color_value.c_str()); - - if (settings->duplex_mode() != - printing::mojom::DuplexMode::kUnknownDuplexMode) { - const char* cups_duplex_mode = nullptr; - switch (settings->duplex_mode()) { - case printing::mojom::DuplexMode::kLongEdge: - cups_duplex_mode = kDuplexNoTumble; - break; - case printing::mojom::DuplexMode::kShortEdge: - cups_duplex_mode = kDuplexTumble; - break; - case printing::mojom::DuplexMode::kSimplex: - cups_duplex_mode = kDuplexNone; - break; - default: // kUnknownDuplexMode - NOTREACHED(); - break; - } - gtk_print_settings_set(gtk_settings_, kCUPSDuplex, cups_duplex_mode); - } -#endif - - if (!page_setup_) - page_setup_ = gtk_page_setup_new(); - - if (page_setup_ && !settings->requested_media().IsDefault()) { - const PrintSettings::RequestedMedia& requested_media = - settings->requested_media(); - GtkPaperSize* gtk_current_paper_size = - gtk_page_setup_get_paper_size(page_setup_); - if (!PaperSizeMatch(gtk_current_paper_size, requested_media, - true /*fuzzy_match*/)) { - GList* gtk_paper_sizes = - gtk_paper_size_get_paper_sizes(false /*include_custom*/); - if (gtk_paper_sizes) { - GtkPaperSize* matching_gtk_paper_size = - FindPaperSizeMatch(gtk_paper_sizes, requested_media); - if (matching_gtk_paper_size) { - VLOG(1) << "Using listed paper size"; - gtk_page_setup_set_paper_size(page_setup_, matching_gtk_paper_size); - } else { - VLOG(1) << "Using custom paper size"; - GtkPaperSize* custom_size = gtk_paper_size_new_custom( - requested_media.vendor_id.c_str(), - requested_media.vendor_id.c_str(), - requested_media.size_microns.width() / kMicronsInMm, - requested_media.size_microns.height() / kMicronsInMm, - GTK_UNIT_MM); - gtk_page_setup_set_paper_size(page_setup_, custom_size); - gtk_paper_size_free(custom_size); - } - g_list_free_full(gtk_paper_sizes, - reinterpret_cast(gtk_paper_size_free)); - } - } else { - VLOG(1) << "Using default paper size"; - } - } - - gtk_print_settings_set_orientation( - gtk_settings_, settings->landscape() ? GTK_PAGE_ORIENTATION_LANDSCAPE - : GTK_PAGE_ORIENTATION_PORTRAIT); - - InitPrintSettings(std::move(settings)); -} - -void PrintDialogGtk::ShowDialog( - gfx::NativeView parent_view, - bool has_selection, - PrintingContextLinux::PrintSettingsCallback callback) { - callback_ = std::move(callback); - DCHECK(callback_); - - dialog_ = gtk_print_unix_dialog_new(nullptr, nullptr); - gtk::SetGtkTransientForAura(dialog_, parent_view); - if (parent_view) - parent_view->AddObserver(this); - g_signal_connect(dialog_, "delete-event", - G_CALLBACK(gtk_widget_hide_on_delete), nullptr); - - // Handle the case when the existing |gtk_settings_| has "selection" selected - // as the page range, but |has_selection| is false. - if (!has_selection) { - GtkPrintPages range = gtk_print_settings_get_print_pages(gtk_settings_); - if (range == GTK_PRINT_PAGES_SELECTION) - gtk_print_settings_set_print_pages(gtk_settings_, GTK_PRINT_PAGES_ALL); - } - - // Set modal so user cannot focus the same tab and press print again. - gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE); - - // Since we only generate PDF, only show printers that support PDF. - // TODO(thestig) Add more capabilities to support? - GtkPrintCapabilities cap = static_cast( - GTK_PRINT_CAPABILITY_GENERATE_PDF | GTK_PRINT_CAPABILITY_PAGE_SET | - GTK_PRINT_CAPABILITY_COPIES | GTK_PRINT_CAPABILITY_COLLATE | - GTK_PRINT_CAPABILITY_REVERSE); - gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(dialog_), - cap); - gtk_print_unix_dialog_set_embed_page_setup(GTK_PRINT_UNIX_DIALOG(dialog_), - TRUE); - gtk_print_unix_dialog_set_support_selection(GTK_PRINT_UNIX_DIALOG(dialog_), - TRUE); - gtk_print_unix_dialog_set_has_selection(GTK_PRINT_UNIX_DIALOG(dialog_), - has_selection); - gtk_print_unix_dialog_set_settings(GTK_PRINT_UNIX_DIALOG(dialog_), - gtk_settings_); - g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); - gtk_widget_show(dialog_); - - gtk::GtkUi::GetDelegate()->ShowGtkWindow(GTK_WINDOW(dialog_)); -} - -void PrintDialogGtk::PrintDocument(const printing::MetafilePlayer& metafile, - const base::string16& document_name) { - // This runs on the print worker thread, does not block the UI thread. - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - // The document printing tasks can outlive the PrintingContext that created - // this dialog. - AddRef(); - - bool success = base::CreateTemporaryFile(&path_to_pdf_); - - if (success) { - base::File file; - file.Initialize(path_to_pdf_, - base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); - success = metafile.SaveTo(&file); - file.Close(); - if (!success) - base::DeleteFile(path_to_pdf_, false); - } - - if (!success) { - LOG(ERROR) << "Saving metafile failed"; - // Matches AddRef() above. - Release(); - return; - } - - // No errors, continue printing. - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&PrintDialogGtk::SendDocumentToPrinter, this, - document_name)); -} - -void PrintDialogGtk::AddRefToDialog() { - AddRef(); -} - -void PrintDialogGtk::ReleaseDialog() { - Release(); -} - -void PrintDialogGtk::OnResponse(GtkWidget* dialog, int response_id) { - int num_matched_handlers = g_signal_handlers_disconnect_by_func( - dialog_, reinterpret_cast(&OnResponseThunk), this); - CHECK_EQ(1, num_matched_handlers); - - gtk_widget_hide(dialog_); - - switch (response_id) { - case GTK_RESPONSE_OK: { - if (gtk_settings_) - g_object_unref(gtk_settings_); - gtk_settings_ = - gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog_)); - - if (printer_) - g_object_unref(printer_); - printer_ = gtk_print_unix_dialog_get_selected_printer( - GTK_PRINT_UNIX_DIALOG(dialog_)); - g_object_ref(printer_); - - if (page_setup_) - g_object_unref(page_setup_); - page_setup_ = - gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dialog_)); - g_object_ref(page_setup_); - - // Handle page ranges. - PageRanges ranges_vector; - gint num_ranges; - bool print_selection_only = false; - switch (gtk_print_settings_get_print_pages(gtk_settings_)) { - case GTK_PRINT_PAGES_RANGES: { - GtkPageRange* gtk_range = - gtk_print_settings_get_page_ranges(gtk_settings_, &num_ranges); - if (gtk_range) { - for (int i = 0; i < num_ranges; ++i) { - printing::PageRange range; - range.from = gtk_range[i].start; - range.to = gtk_range[i].end; - ranges_vector.push_back(range); - } - g_free(gtk_range); - } - break; - } - case GTK_PRINT_PAGES_SELECTION: - print_selection_only = true; - break; - case GTK_PRINT_PAGES_ALL: - // Leave |ranges_vector| empty to indicate print all pages. - break; - case GTK_PRINT_PAGES_CURRENT: - default: - NOTREACHED(); - break; - } - - auto settings = std::make_unique(); - settings->set_is_modifiable(context_->settings().is_modifiable()); - settings->set_ranges(ranges_vector); - settings->set_selection_only(print_selection_only); - InitPrintSettingsGtk(gtk_settings_, page_setup_, settings.get()); - context_->InitWithSettings(std::move(settings)); - std::move(callback_).Run(PrintingContextLinux::OK); - return; - } - case GTK_RESPONSE_DELETE_EVENT: // Fall through. - case GTK_RESPONSE_CANCEL: { - std::move(callback_).Run(PrintingContextLinux::CANCEL); - return; - } - case GTK_RESPONSE_APPLY: - default: { - NOTREACHED(); - } - } -} - -static void OnJobCompletedThunk(GtkPrintJob* print_job, - gpointer user_data, - const GError* error) { - static_cast(user_data)->OnJobCompleted(print_job, error); -} -void PrintDialogGtk::SendDocumentToPrinter( - const base::string16& document_name) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - // If |printer_| is nullptr then somehow the GTK printer list changed out - // under us. In which case, just bail out. - if (!printer_) { - // Matches AddRef() in PrintDocument(); - Release(); - return; - } - - // Save the settings for next time. - GetLastUsedSettings().SetLastUsedSettings(gtk_settings_); - - GtkPrintJob* print_job = - gtk_print_job_new(base::UTF16ToUTF8(document_name).c_str(), printer_, - gtk_settings_, page_setup_); - gtk_print_job_set_source_file(print_job, path_to_pdf_.value().c_str(), - nullptr); - gtk_print_job_send(print_job, OnJobCompletedThunk, this, nullptr); -} - -void PrintDialogGtk::OnJobCompleted(GtkPrintJob* print_job, - const GError* error) { - if (error) - LOG(ERROR) << "Printing failed: " << error->message; - if (print_job) - g_object_unref(print_job); - - base::ThreadPool::PostTask( - FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, - base::BindOnce(base::IgnoreResult(&base::DeleteFile), path_to_pdf_, - false)); - // Printing finished. Matches AddRef() in PrintDocument(); - Release(); -} - -void PrintDialogGtk::InitPrintSettings( - std::unique_ptr settings) { - InitPrintSettingsGtk(gtk_settings_, page_setup_, settings.get()); - context_->InitWithSettings(std::move(settings)); -} - -void PrintDialogGtk::OnWindowDestroying(aura::Window* window) { - DCHECK_EQ(gtk::GetAuraTransientParent(dialog_), window); - - gtk::ClearAuraTransientParent(dialog_); - window->RemoveObserver(this); - if (callback_) - std::move(callback_).Run(PrintingContextLinux::CANCEL); -} diff --git a/chromium/ui/gtk/print_dialog_gtk.h b/chromium/ui/gtk/print_dialog_gtk.h deleted file mode 100644 index b7874e587f5..00000000000 --- a/chromium/ui/gtk/print_dialog_gtk.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_GTK_PRINT_DIALOG_GTK_H_ -#define UI_GTK_PRINT_DIALOG_GTK_H_ - -#include -#include -#include - -#include "base/compiler_specific.h" -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/ref_counted_delete_on_sequence.h" -#include "base/sequenced_task_runner_helpers.h" -#include "printing/print_dialog_gtk_interface.h" -#include "printing/printing_context_linux.h" -#include "ui/aura/window_observer.h" -#include "ui/base/glib/glib_signal.h" - -namespace printing { -class MetafilePlayer; -class PrintSettings; -} // namespace printing - -using printing::PrintingContextLinux; - -// Needs to be freed on the UI thread to clean up its GTK members variables. -class PrintDialogGtk : public printing::PrintDialogGtkInterface, - public base::RefCountedDeleteOnSequence, - public aura::WindowObserver { - public: - // Creates and returns a print dialog. - static printing::PrintDialogGtkInterface* CreatePrintDialog( - PrintingContextLinux* context); - - // printing::PrintDialogGtkInterface implementation. - void UseDefaultSettings() override; - void UpdateSettings( - std::unique_ptr settings) override; - void ShowDialog( - gfx::NativeView parent_view, - bool has_selection, - PrintingContextLinux::PrintSettingsCallback callback) override; - void PrintDocument(const printing::MetafilePlayer& metafile, - const base::string16& document_name) override; - void AddRefToDialog() override; - void ReleaseDialog() override; - - // Handles print job response. - void OnJobCompleted(GtkPrintJob* print_job, const GError* error); - - private: - friend class base::RefCountedDeleteOnSequence; - friend class base::DeleteHelper; - - explicit PrintDialogGtk(PrintingContextLinux* context); - ~PrintDialogGtk() override; - - // Handles dialog response. - CHROMEG_CALLBACK_1(PrintDialogGtk, void, OnResponse, GtkWidget*, int); - - // Prints document named |document_name|. - void SendDocumentToPrinter(const base::string16& document_name); - - // Helper function for initializing |context_|'s PrintSettings with a given - // |settings|. - void InitPrintSettings(std::unique_ptr settings); - - // aura::WindowObserver implementation. - void OnWindowDestroying(aura::Window* window) override; - - // Printing dialog callback. - PrintingContextLinux::PrintSettingsCallback callback_; - PrintingContextLinux* const context_; - - // Print dialog settings. PrintDialogGtk owns |dialog_| and holds references - // to the other objects. - GtkWidget* dialog_ = nullptr; - GtkPrintSettings* gtk_settings_ = nullptr; - GtkPageSetup* page_setup_ = nullptr; - GtkPrinter* printer_ = nullptr; - - base::FilePath path_to_pdf_; - - SEQUENCE_CHECKER(sequence_checker_); - - DISALLOW_COPY_AND_ASSIGN(PrintDialogGtk); -}; - -#endif // UI_GTK_PRINT_DIALOG_GTK_H_ diff --git a/chromium/ui/gtk/printing/OWNERS b/chromium/ui/gtk/printing/OWNERS new file mode 100644 index 00000000000..d50bb849014 --- /dev/null +++ b/chromium/ui/gtk/printing/OWNERS @@ -0,0 +1,3 @@ +file://printing/OWNERS + +# COMPONENT: Internals>Printing diff --git a/chromium/ui/gtk/printing/print_dialog_gtk.cc b/chromium/ui/gtk/printing/print_dialog_gtk.cc new file mode 100644 index 00000000000..57900d2854d --- /dev/null +++ b/chromium/ui/gtk/printing/print_dialog_gtk.cc @@ -0,0 +1,551 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gtk/printing/print_dialog_gtk.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/no_destructor.h" +#include "base/sequence_checker.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task/post_task.h" +#include "base/task/thread_pool.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "base/values.h" +#include "printing/metafile.h" +#include "printing/print_job_constants.h" +#include "printing/print_settings.h" +#include "ui/aura/window.h" +#include "ui/gtk/gtk_ui.h" +#include "ui/gtk/gtk_ui_delegate.h" +#include "ui/gtk/gtk_util.h" +#include "ui/gtk/printing/printing_gtk_util.h" + +#if defined(USE_CUPS) +#include "printing/mojom/print.mojom.h" +#endif + +using printing::PageRanges; +using printing::PrintSettings; + +namespace { + +#if defined(USE_CUPS) +// CUPS Duplex attribute and values. +const char kCUPSDuplex[] = "cups-Duplex"; +const char kDuplexNone[] = "None"; +const char kDuplexTumble[] = "DuplexTumble"; +const char kDuplexNoTumble[] = "DuplexNoTumble"; +#endif + +constexpr int kPaperSizeTresholdMicrons = 100; +constexpr int kMicronsInMm = 1000; + +// Checks whether |gtk_paper_size| can be used to represent user selected media. +// In fuzzy match mode checks that paper sizes are "close enough" (less than +// 1mm difference). In the exact mode, looks for the paper with the same PPD +// name and "close enough" size. +bool PaperSizeMatch(GtkPaperSize* gtk_paper_size, + const PrintSettings::RequestedMedia& media, + bool fuzzy_match) { + if (!gtk_paper_size) + return false; + + gfx::Size paper_size_microns( + static_cast(gtk_paper_size_get_width(gtk_paper_size, GTK_UNIT_MM) * + kMicronsInMm + + 0.5), + static_cast(gtk_paper_size_get_height(gtk_paper_size, GTK_UNIT_MM) * + kMicronsInMm + + 0.5)); + int diff = std::max( + std::abs(paper_size_microns.width() - media.size_microns.width()), + std::abs(paper_size_microns.height() - media.size_microns.height())); + bool close_enough = diff <= kPaperSizeTresholdMicrons; + if (fuzzy_match) + return close_enough; + + return close_enough && !media.vendor_id.empty() && + media.vendor_id == gtk_paper_size_get_ppd_name(gtk_paper_size); +} + +// Looks up a paper size matching (in terms of PaperSizeMatch) the user selected +// media in the paper size list reported by GTK. Returns nullptr if there's no +// match found. +GtkPaperSize* FindPaperSizeMatch(GList* gtk_paper_sizes, + const PrintSettings::RequestedMedia& media) { + GtkPaperSize* first_fuzzy_match = nullptr; + for (GList* p = gtk_paper_sizes; p && p->data; p = g_list_next(p)) { + GtkPaperSize* gtk_paper_size = static_cast(p->data); + if (PaperSizeMatch(gtk_paper_size, media, false)) + return gtk_paper_size; + + if (!first_fuzzy_match && PaperSizeMatch(gtk_paper_size, media, true)) + first_fuzzy_match = gtk_paper_size; + } + return first_fuzzy_match; +} + +class StickyPrintSettingGtk { + public: + StickyPrintSettingGtk() : last_used_settings_(gtk_print_settings_new()) {} + ~StickyPrintSettingGtk() { + NOTREACHED(); // Intended to be used with base::NoDestructor. + } + + GtkPrintSettings* settings() { return last_used_settings_; } + + void SetLastUsedSettings(GtkPrintSettings* settings) { + DCHECK(last_used_settings_); + g_object_unref(last_used_settings_); + last_used_settings_ = gtk_print_settings_copy(settings); + } + + private: + GtkPrintSettings* last_used_settings_; + + DISALLOW_COPY_AND_ASSIGN(StickyPrintSettingGtk); +}; + +StickyPrintSettingGtk& GetLastUsedSettings() { + static base::NoDestructor settings; + return *settings; +} + +// Helper class to track GTK printers. +class GtkPrinterList { + public: + GtkPrinterList() { gtk_enumerate_printers(SetPrinter, this, nullptr, TRUE); } + + ~GtkPrinterList() { + for (GtkPrinter* printer : printers_) + g_object_unref(printer); + } + + // Can return nullptr if there's no default printer. E.g. Printer on a laptop + // is "home_printer", but the laptop is at work. + GtkPrinter* default_printer() { return default_printer_; } + + // Can return nullptr if the printer cannot be found due to: + // - Printer list out of sync with printer dialog UI. + // - Querying for non-existant printers like 'Print to PDF'. + GtkPrinter* GetPrinterWithName(const std::string& name) { + if (name.empty()) + return nullptr; + + for (GtkPrinter* printer : printers_) { + if (gtk_printer_get_name(printer) == name) + return printer; + } + + return nullptr; + } + + private: + // Callback function used by gtk_enumerate_printers() to get all printer. + static gboolean SetPrinter(GtkPrinter* printer, gpointer data) { + GtkPrinterList* printer_list = reinterpret_cast(data); + if (gtk_printer_is_default(printer)) + printer_list->default_printer_ = printer; + + g_object_ref(printer); + printer_list->printers_.push_back(printer); + + return FALSE; + } + + std::vector printers_; + GtkPrinter* default_printer_ = nullptr; +}; + +} // namespace + +// static +printing::PrintDialogGtkInterface* PrintDialogGtk::CreatePrintDialog( + PrintingContextLinux* context) { + return new PrintDialogGtk(context); +} + +PrintDialogGtk::PrintDialogGtk(PrintingContextLinux* context) + : base::RefCountedDeleteOnSequence( + base::SequencedTaskRunnerHandle::Get()), + context_(context) {} + +PrintDialogGtk::~PrintDialogGtk() { + DCHECK(owning_task_runner()->RunsTasksInCurrentSequence()); + + if (dialog_) { + aura::Window* parent = gtk::GetAuraTransientParent(dialog_); + if (parent) { + parent->RemoveObserver(this); + gtk::ClearAuraTransientParent(dialog_); + } + gtk_widget_destroy(dialog_); + dialog_ = nullptr; + } + if (gtk_settings_) { + g_object_unref(gtk_settings_); + gtk_settings_ = nullptr; + } + if (page_setup_) { + g_object_unref(page_setup_); + page_setup_ = nullptr; + } + if (printer_) { + g_object_unref(printer_); + printer_ = nullptr; + } +} + +void PrintDialogGtk::UseDefaultSettings() { + DCHECK(!page_setup_); + DCHECK(!printer_); + + // |gtk_settings_| is a new copy. + gtk_settings_ = gtk_print_settings_copy(GetLastUsedSettings().settings()); + page_setup_ = gtk_page_setup_new(); + + InitPrintSettings(std::make_unique()); +} + +void PrintDialogGtk::UpdateSettings( + std::unique_ptr settings) { + if (!gtk_settings_) + gtk_settings_ = gtk_print_settings_copy(GetLastUsedSettings().settings()); + + auto printer_list = std::make_unique(); + printer_ = printer_list->GetPrinterWithName( + base::UTF16ToUTF8(settings->device_name())); + if (printer_) { + g_object_ref(printer_); + gtk_print_settings_set_printer(gtk_settings_, + gtk_printer_get_name(printer_)); + if (!page_setup_) { + page_setup_ = gtk_printer_get_default_page_size(printer_); + } + } + + gtk_print_settings_set_n_copies(gtk_settings_, settings->copies()); + gtk_print_settings_set_collate(gtk_settings_, settings->collate()); + +#if defined(USE_CUPS) + // Set advanced settings first so they can be overridden by user applied + // settings. + for (const auto& pair : settings->advanced_settings()) { + if (!pair.second.is_string()) + continue; + static constexpr char kSettingNamePrefix[] = "cups-"; + const std::string setting_name = kSettingNamePrefix + pair.first; + gtk_print_settings_set(gtk_settings_, setting_name.c_str(), + pair.second.GetString().c_str()); + } + + std::string color_value; + std::string color_setting_name; + printing::GetColorModelForMode(settings->color(), &color_setting_name, + &color_value); + gtk_print_settings_set(gtk_settings_, color_setting_name.c_str(), + color_value.c_str()); + + if (settings->duplex_mode() != + printing::mojom::DuplexMode::kUnknownDuplexMode) { + const char* cups_duplex_mode = nullptr; + switch (settings->duplex_mode()) { + case printing::mojom::DuplexMode::kLongEdge: + cups_duplex_mode = kDuplexNoTumble; + break; + case printing::mojom::DuplexMode::kShortEdge: + cups_duplex_mode = kDuplexTumble; + break; + case printing::mojom::DuplexMode::kSimplex: + cups_duplex_mode = kDuplexNone; + break; + default: // kUnknownDuplexMode + NOTREACHED(); + break; + } + gtk_print_settings_set(gtk_settings_, kCUPSDuplex, cups_duplex_mode); + } +#endif + + if (!page_setup_) + page_setup_ = gtk_page_setup_new(); + + if (page_setup_ && !settings->requested_media().IsDefault()) { + const PrintSettings::RequestedMedia& requested_media = + settings->requested_media(); + GtkPaperSize* gtk_current_paper_size = + gtk_page_setup_get_paper_size(page_setup_); + if (!PaperSizeMatch(gtk_current_paper_size, requested_media, + true /*fuzzy_match*/)) { + GList* gtk_paper_sizes = + gtk_paper_size_get_paper_sizes(false /*include_custom*/); + if (gtk_paper_sizes) { + GtkPaperSize* matching_gtk_paper_size = + FindPaperSizeMatch(gtk_paper_sizes, requested_media); + if (matching_gtk_paper_size) { + VLOG(1) << "Using listed paper size"; + gtk_page_setup_set_paper_size(page_setup_, matching_gtk_paper_size); + } else { + VLOG(1) << "Using custom paper size"; + GtkPaperSize* custom_size = gtk_paper_size_new_custom( + requested_media.vendor_id.c_str(), + requested_media.vendor_id.c_str(), + requested_media.size_microns.width() / kMicronsInMm, + requested_media.size_microns.height() / kMicronsInMm, + GTK_UNIT_MM); + gtk_page_setup_set_paper_size(page_setup_, custom_size); + gtk_paper_size_free(custom_size); + } + g_list_free_full(gtk_paper_sizes, + reinterpret_cast(gtk_paper_size_free)); + } + } else { + VLOG(1) << "Using default paper size"; + } + } + + gtk_print_settings_set_orientation( + gtk_settings_, settings->landscape() ? GTK_PAGE_ORIENTATION_LANDSCAPE + : GTK_PAGE_ORIENTATION_PORTRAIT); + + InitPrintSettings(std::move(settings)); +} + +void PrintDialogGtk::ShowDialog( + gfx::NativeView parent_view, + bool has_selection, + PrintingContextLinux::PrintSettingsCallback callback) { + callback_ = std::move(callback); + DCHECK(callback_); + + dialog_ = gtk_print_unix_dialog_new(nullptr, nullptr); + gtk::SetGtkTransientForAura(dialog_, parent_view); + if (parent_view) + parent_view->AddObserver(this); + g_signal_connect(dialog_, "delete-event", + G_CALLBACK(gtk_widget_hide_on_delete), nullptr); + + // Handle the case when the existing |gtk_settings_| has "selection" selected + // as the page range, but |has_selection| is false. + if (!has_selection) { + GtkPrintPages range = gtk_print_settings_get_print_pages(gtk_settings_); + if (range == GTK_PRINT_PAGES_SELECTION) + gtk_print_settings_set_print_pages(gtk_settings_, GTK_PRINT_PAGES_ALL); + } + + // Set modal so user cannot focus the same tab and press print again. + gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE); + + // Since we only generate PDF, only show printers that support PDF. + // TODO(thestig) Add more capabilities to support? + GtkPrintCapabilities cap = static_cast( + GTK_PRINT_CAPABILITY_GENERATE_PDF | GTK_PRINT_CAPABILITY_PAGE_SET | + GTK_PRINT_CAPABILITY_COPIES | GTK_PRINT_CAPABILITY_COLLATE | + GTK_PRINT_CAPABILITY_REVERSE); + gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(dialog_), + cap); + gtk_print_unix_dialog_set_embed_page_setup(GTK_PRINT_UNIX_DIALOG(dialog_), + TRUE); + gtk_print_unix_dialog_set_support_selection(GTK_PRINT_UNIX_DIALOG(dialog_), + TRUE); + gtk_print_unix_dialog_set_has_selection(GTK_PRINT_UNIX_DIALOG(dialog_), + has_selection); + gtk_print_unix_dialog_set_settings(GTK_PRINT_UNIX_DIALOG(dialog_), + gtk_settings_); + g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); + gtk_widget_show(dialog_); + + gtk::GtkUi::GetDelegate()->ShowGtkWindow(GTK_WINDOW(dialog_)); +} + +void PrintDialogGtk::PrintDocument(const printing::MetafilePlayer& metafile, + const base::string16& document_name) { + // This runs on the print worker thread, does not block the UI thread. + DCHECK(!owning_task_runner()->RunsTasksInCurrentSequence()); + + // The document printing tasks can outlive the PrintingContext that created + // this dialog. + AddRef(); + + bool success = base::CreateTemporaryFile(&path_to_pdf_); + + if (success) { + base::File file; + file.Initialize(path_to_pdf_, + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + success = metafile.SaveTo(&file); + file.Close(); + if (!success) + base::DeleteFile(path_to_pdf_, false); + } + + if (!success) { + LOG(ERROR) << "Saving metafile failed"; + // Matches AddRef() above. + Release(); + return; + } + + // No errors, continue printing. + owning_task_runner()->PostTask( + FROM_HERE, base::BindOnce(&PrintDialogGtk::SendDocumentToPrinter, this, + document_name)); +} + +void PrintDialogGtk::AddRefToDialog() { + AddRef(); +} + +void PrintDialogGtk::ReleaseDialog() { + Release(); +} + +void PrintDialogGtk::OnResponse(GtkWidget* dialog, int response_id) { + int num_matched_handlers = g_signal_handlers_disconnect_by_func( + dialog_, reinterpret_cast(&OnResponseThunk), this); + CHECK_EQ(1, num_matched_handlers); + + gtk_widget_hide(dialog_); + + switch (response_id) { + case GTK_RESPONSE_OK: { + if (gtk_settings_) + g_object_unref(gtk_settings_); + gtk_settings_ = + gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog_)); + + if (printer_) + g_object_unref(printer_); + printer_ = gtk_print_unix_dialog_get_selected_printer( + GTK_PRINT_UNIX_DIALOG(dialog_)); + g_object_ref(printer_); + + if (page_setup_) + g_object_unref(page_setup_); + page_setup_ = + gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dialog_)); + g_object_ref(page_setup_); + + // Handle page ranges. + PageRanges ranges_vector; + gint num_ranges; + bool print_selection_only = false; + switch (gtk_print_settings_get_print_pages(gtk_settings_)) { + case GTK_PRINT_PAGES_RANGES: { + GtkPageRange* gtk_range = + gtk_print_settings_get_page_ranges(gtk_settings_, &num_ranges); + if (gtk_range) { + for (int i = 0; i < num_ranges; ++i) { + printing::PageRange range; + range.from = gtk_range[i].start; + range.to = gtk_range[i].end; + ranges_vector.push_back(range); + } + g_free(gtk_range); + } + break; + } + case GTK_PRINT_PAGES_SELECTION: + print_selection_only = true; + break; + case GTK_PRINT_PAGES_ALL: + // Leave |ranges_vector| empty to indicate print all pages. + break; + case GTK_PRINT_PAGES_CURRENT: + default: + NOTREACHED(); + break; + } + + auto settings = std::make_unique(); + settings->set_is_modifiable(context_->settings().is_modifiable()); + settings->set_ranges(ranges_vector); + settings->set_selection_only(print_selection_only); + InitPrintSettingsGtk(gtk_settings_, page_setup_, settings.get()); + context_->InitWithSettings(std::move(settings)); + std::move(callback_).Run(PrintingContextLinux::OK); + return; + } + case GTK_RESPONSE_DELETE_EVENT: // Fall through. + case GTK_RESPONSE_CANCEL: { + std::move(callback_).Run(PrintingContextLinux::CANCEL); + return; + } + case GTK_RESPONSE_APPLY: + default: { + NOTREACHED(); + } + } +} + +static void OnJobCompletedThunk(GtkPrintJob* print_job, + gpointer user_data, + const GError* error) { + static_cast(user_data)->OnJobCompleted(print_job, error); +} +void PrintDialogGtk::SendDocumentToPrinter( + const base::string16& document_name) { + DCHECK(owning_task_runner()->RunsTasksInCurrentSequence()); + + // If |printer_| is nullptr then somehow the GTK printer list changed out + // under us. In which case, just bail out. + if (!printer_) { + // Matches AddRef() in PrintDocument(); + Release(); + return; + } + + // Save the settings for next time. + GetLastUsedSettings().SetLastUsedSettings(gtk_settings_); + + GtkPrintJob* print_job = + gtk_print_job_new(base::UTF16ToUTF8(document_name).c_str(), printer_, + gtk_settings_, page_setup_); + gtk_print_job_set_source_file(print_job, path_to_pdf_.value().c_str(), + nullptr); + gtk_print_job_send(print_job, OnJobCompletedThunk, this, nullptr); +} + +void PrintDialogGtk::OnJobCompleted(GtkPrintJob* print_job, + const GError* error) { + if (error) + LOG(ERROR) << "Printing failed: " << error->message; + if (print_job) + g_object_unref(print_job); + + base::ThreadPool::PostTask( + FROM_HERE, + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, + base::BindOnce(base::GetDeleteFileCallback(), path_to_pdf_)); + // Printing finished. Matches AddRef() in PrintDocument(); + Release(); +} + +void PrintDialogGtk::InitPrintSettings( + std::unique_ptr settings) { + InitPrintSettingsGtk(gtk_settings_, page_setup_, settings.get()); + context_->InitWithSettings(std::move(settings)); +} + +void PrintDialogGtk::OnWindowDestroying(aura::Window* window) { + DCHECK_EQ(gtk::GetAuraTransientParent(dialog_), window); + + gtk::ClearAuraTransientParent(dialog_); + window->RemoveObserver(this); + if (callback_) + std::move(callback_).Run(PrintingContextLinux::CANCEL); +} diff --git a/chromium/ui/gtk/printing/print_dialog_gtk.h b/chromium/ui/gtk/printing/print_dialog_gtk.h new file mode 100644 index 00000000000..f065848a163 --- /dev/null +++ b/chromium/ui/gtk/printing/print_dialog_gtk.h @@ -0,0 +1,89 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GTK_PRINTING_PRINT_DIALOG_GTK_H_ +#define UI_GTK_PRINTING_PRINT_DIALOG_GTK_H_ + +#include +#include +#include + +#include "base/compiler_specific.h" +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/memory/ref_counted_delete_on_sequence.h" +#include "printing/print_dialog_gtk_interface.h" +#include "printing/printing_context_linux.h" +#include "ui/aura/window_observer.h" +#include "ui/base/glib/glib_signal.h" + +namespace printing { +class MetafilePlayer; +class PrintSettings; +} // namespace printing + +using printing::PrintingContextLinux; + +// Needs to be freed on the UI thread to clean up its GTK members variables. +class PrintDialogGtk : public printing::PrintDialogGtkInterface, + public base::RefCountedDeleteOnSequence, + public aura::WindowObserver { + public: + // Creates and returns a print dialog. + static printing::PrintDialogGtkInterface* CreatePrintDialog( + PrintingContextLinux* context); + + // printing::PrintDialogGtkInterface implementation. + void UseDefaultSettings() override; + void UpdateSettings( + std::unique_ptr settings) override; + void ShowDialog( + gfx::NativeView parent_view, + bool has_selection, + PrintingContextLinux::PrintSettingsCallback callback) override; + void PrintDocument(const printing::MetafilePlayer& metafile, + const base::string16& document_name) override; + void AddRefToDialog() override; + void ReleaseDialog() override; + + // Handles print job response. + void OnJobCompleted(GtkPrintJob* print_job, const GError* error); + + private: + friend class base::RefCountedDeleteOnSequence; + friend class base::DeleteHelper; + + explicit PrintDialogGtk(PrintingContextLinux* context); + ~PrintDialogGtk() override; + + // Handles dialog response. + CHROMEG_CALLBACK_1(PrintDialogGtk, void, OnResponse, GtkWidget*, int); + + // Prints document named |document_name|. + void SendDocumentToPrinter(const base::string16& document_name); + + // Helper function for initializing |context_|'s PrintSettings with a given + // |settings|. + void InitPrintSettings(std::unique_ptr settings); + + // aura::WindowObserver implementation. + void OnWindowDestroying(aura::Window* window) override; + + // Printing dialog callback. + PrintingContextLinux::PrintSettingsCallback callback_; + PrintingContextLinux* const context_; + + // Print dialog settings. PrintDialogGtk owns |dialog_| and holds references + // to the other objects. + GtkWidget* dialog_ = nullptr; + GtkPrintSettings* gtk_settings_ = nullptr; + GtkPageSetup* page_setup_ = nullptr; + GtkPrinter* printer_ = nullptr; + + base::FilePath path_to_pdf_; + + DISALLOW_COPY_AND_ASSIGN(PrintDialogGtk); +}; + +#endif // UI_GTK_PRINTING_PRINT_DIALOG_GTK_H_ diff --git a/chromium/ui/gtk/printing/printing_gtk_util.cc b/chromium/ui/gtk/printing/printing_gtk_util.cc new file mode 100644 index 00000000000..fe3771f808b --- /dev/null +++ b/chromium/ui/gtk/printing/printing_gtk_util.cc @@ -0,0 +1,96 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gtk/printing/printing_gtk_util.h" + +#include +#include + +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "printing/print_settings.h" +#include "printing/printing_context_linux.h" +#include "printing/units.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/size_f.h" + +namespace { + +const double kTopMarginInInch = 0.25; +const double kBottomMarginInInch = 0.56; +const double kLeftMarginInInch = 0.25; +const double kRightMarginInInch = 0.25; + +} // namespace + +gfx::Size GetPdfPaperSizeDeviceUnitsGtk( + printing::PrintingContextLinux* context) { + GtkPageSetup* page_setup = gtk_page_setup_new(); + + gfx::SizeF paper_size( + gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH), + gtk_page_setup_get_paper_height(page_setup, GTK_UNIT_INCH)); + + g_object_unref(page_setup); + + const printing::PrintSettings& settings = context->settings(); + + return gfx::Size(paper_size.width() * settings.device_units_per_inch(), + paper_size.height() * settings.device_units_per_inch()); +} + +void InitPrintSettingsGtk(GtkPrintSettings* settings, + GtkPageSetup* page_setup, + printing::PrintSettings* print_settings) { + DCHECK(settings); + DCHECK(page_setup); + DCHECK(print_settings); + + base::string16 name(base::UTF8ToUTF16( + static_cast(gtk_print_settings_get_printer(settings)))); + print_settings->set_device_name(name); + + gfx::Size physical_size_device_units; + gfx::Rect printable_area_device_units; + int dpi = gtk_print_settings_get_resolution(settings); + if (dpi) { + // Initialize page_setup_device_units_. + physical_size_device_units.SetSize( + gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH) * dpi, + gtk_page_setup_get_paper_height(page_setup, GTK_UNIT_INCH) * dpi); + printable_area_device_units.SetRect( + gtk_page_setup_get_left_margin(page_setup, GTK_UNIT_INCH) * dpi, + gtk_page_setup_get_top_margin(page_setup, GTK_UNIT_INCH) * dpi, + gtk_page_setup_get_page_width(page_setup, GTK_UNIT_INCH) * dpi, + gtk_page_setup_get_page_height(page_setup, GTK_UNIT_INCH) * dpi); + } else { + // Use default values if we cannot get valid values from the print dialog. + dpi = printing::kPixelsPerInch; + double page_width_in_pixel = printing::kLetterWidthInch * dpi; + double page_height_in_pixel = printing::kLetterHeightInch * dpi; + physical_size_device_units.SetSize(static_cast(page_width_in_pixel), + static_cast(page_height_in_pixel)); + printable_area_device_units.SetRect( + static_cast(kLeftMarginInInch * dpi), + static_cast(kTopMarginInInch * dpi), + page_width_in_pixel - (kLeftMarginInInch + kRightMarginInInch) * dpi, + page_height_in_pixel - (kTopMarginInInch + kBottomMarginInInch) * dpi); + } + + print_settings->set_dpi(dpi); + + // Note: With the normal GTK print dialog, when the user selects the landscape + // orientation, all that does is change the paper size. Which seems to be + // enough to render the right output and send it to the printer. + // The orientation value stays as portrait and does not actually affect + // printing. + // Thus this is only useful in print preview mode, where we manually set the + // orientation and change the paper size ourselves. + GtkPageOrientation orientation = gtk_print_settings_get_orientation(settings); + // Set before SetPrinterPrintableArea to make it flip area if necessary. + print_settings->SetOrientation(orientation == GTK_PAGE_ORIENTATION_LANDSCAPE); + DCHECK_EQ(print_settings->device_units_per_inch(), dpi); + print_settings->SetPrinterPrintableArea(physical_size_device_units, + printable_area_device_units, true); +} diff --git a/chromium/ui/gtk/printing/printing_gtk_util.h b/chromium/ui/gtk/printing/printing_gtk_util.h new file mode 100644 index 00000000000..7b41010d94a --- /dev/null +++ b/chromium/ui/gtk/printing/printing_gtk_util.h @@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GTK_PRINTING_PRINTING_GTK_UTIL_H_ +#define UI_GTK_PRINTING_PRINTING_GTK_UTIL_H_ + +#include "ui/gfx/geometry/size.h" + +namespace printing { +class PrintingContextLinux; +class PrintSettings; +} // namespace printing + +typedef struct _GtkPrintSettings GtkPrintSettings; +typedef struct _GtkPageSetup GtkPageSetup; + +// Obtains the paper size through Gtk. +gfx::Size GetPdfPaperSizeDeviceUnitsGtk( + printing::PrintingContextLinux* context); + +// Initializes a PrintSettings object from the provided Gtk printer objects. +void InitPrintSettingsGtk(GtkPrintSettings* settings, + GtkPageSetup* page_setup, + printing::PrintSettings* print_settings); + +#endif // UI_GTK_PRINTING_PRINTING_GTK_UTIL_H_ diff --git a/chromium/ui/gtk/printing_gtk_util.cc b/chromium/ui/gtk/printing_gtk_util.cc deleted file mode 100644 index efacf89c209..00000000000 --- a/chromium/ui/gtk/printing_gtk_util.cc +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gtk/printing_gtk_util.h" - -#include -#include - -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "printing/print_settings.h" -#include "printing/printing_context_linux.h" -#include "printing/units.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/geometry/size_f.h" - -namespace { - -const double kTopMarginInInch = 0.25; -const double kBottomMarginInInch = 0.56; -const double kLeftMarginInInch = 0.25; -const double kRightMarginInInch = 0.25; - -} // namespace - -gfx::Size GetPdfPaperSizeDeviceUnitsGtk( - printing::PrintingContextLinux* context) { - GtkPageSetup* page_setup = gtk_page_setup_new(); - - gfx::SizeF paper_size( - gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH), - gtk_page_setup_get_paper_height(page_setup, GTK_UNIT_INCH)); - - g_object_unref(page_setup); - - const printing::PrintSettings& settings = context->settings(); - - return gfx::Size(paper_size.width() * settings.device_units_per_inch(), - paper_size.height() * settings.device_units_per_inch()); -} - -void InitPrintSettingsGtk(GtkPrintSettings* settings, - GtkPageSetup* page_setup, - printing::PrintSettings* print_settings) { - DCHECK(settings); - DCHECK(page_setup); - DCHECK(print_settings); - - base::string16 name(base::UTF8ToUTF16( - static_cast(gtk_print_settings_get_printer(settings)))); - print_settings->set_device_name(name); - - gfx::Size physical_size_device_units; - gfx::Rect printable_area_device_units; - int dpi = gtk_print_settings_get_resolution(settings); - if (dpi) { - // Initialize page_setup_device_units_. - physical_size_device_units.SetSize( - gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH) * dpi, - gtk_page_setup_get_paper_height(page_setup, GTK_UNIT_INCH) * dpi); - printable_area_device_units.SetRect( - gtk_page_setup_get_left_margin(page_setup, GTK_UNIT_INCH) * dpi, - gtk_page_setup_get_top_margin(page_setup, GTK_UNIT_INCH) * dpi, - gtk_page_setup_get_page_width(page_setup, GTK_UNIT_INCH) * dpi, - gtk_page_setup_get_page_height(page_setup, GTK_UNIT_INCH) * dpi); - } else { - // Use default values if we cannot get valid values from the print dialog. - dpi = printing::kPixelsPerInch; - double page_width_in_pixel = printing::kLetterWidthInch * dpi; - double page_height_in_pixel = printing::kLetterHeightInch * dpi; - physical_size_device_units.SetSize(static_cast(page_width_in_pixel), - static_cast(page_height_in_pixel)); - printable_area_device_units.SetRect( - static_cast(kLeftMarginInInch * dpi), - static_cast(kTopMarginInInch * dpi), - page_width_in_pixel - (kLeftMarginInInch + kRightMarginInInch) * dpi, - page_height_in_pixel - (kTopMarginInInch + kBottomMarginInInch) * dpi); - } - - print_settings->set_dpi(dpi); - - // Note: With the normal GTK print dialog, when the user selects the landscape - // orientation, all that does is change the paper size. Which seems to be - // enough to render the right output and send it to the printer. - // The orientation value stays as portrait and does not actually affect - // printing. - // Thus this is only useful in print preview mode, where we manually set the - // orientation and change the paper size ourselves. - GtkPageOrientation orientation = gtk_print_settings_get_orientation(settings); - // Set before SetPrinterPrintableArea to make it flip area if necessary. - print_settings->SetOrientation(orientation == GTK_PAGE_ORIENTATION_LANDSCAPE); - DCHECK_EQ(print_settings->device_units_per_inch(), dpi); - print_settings->SetPrinterPrintableArea(physical_size_device_units, - printable_area_device_units, true); -} diff --git a/chromium/ui/gtk/printing_gtk_util.h b/chromium/ui/gtk/printing_gtk_util.h deleted file mode 100644 index 4dce6f8613f..00000000000 --- a/chromium/ui/gtk/printing_gtk_util.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_GTK_PRINTING_GTK_UTIL_H_ -#define UI_GTK_PRINTING_GTK_UTIL_H_ - -#include "ui/gfx/geometry/size.h" - -namespace printing { -class PrintingContextLinux; -class PrintSettings; -} // namespace printing - -typedef struct _GtkPrintSettings GtkPrintSettings; -typedef struct _GtkPageSetup GtkPageSetup; - -// Obtains the paper size through Gtk. -gfx::Size GetPdfPaperSizeDeviceUnitsGtk( - printing::PrintingContextLinux* context); - -// Initializes a PrintSettings object from the provided Gtk printer objects. -void InitPrintSettingsGtk(GtkPrintSettings* settings, - GtkPageSetup* page_setup, - printing::PrintSettings* print_settings); - -#endif // UI_GTK_PRINTING_GTK_UTIL_H_ diff --git a/chromium/ui/gtk/select_file_dialog_impl_kde.cc b/chromium/ui/gtk/select_file_dialog_impl_kde.cc index f09501d6cd8..4eba97d573d 100644 --- a/chromium/ui/gtk/select_file_dialog_impl_kde.cc +++ b/chromium/ui/gtk/select_file_dialog_impl_kde.cc @@ -75,7 +75,7 @@ class SelectFileDialogImplKDE : public SelectFileDialogImpl { KDialogParams(const std::string& type, const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, bool file_operation, bool multiple_selection) : type(type), @@ -88,7 +88,7 @@ class SelectFileDialogImplKDE : public SelectFileDialogImpl { std::string type; std::string title; base::FilePath default_path; - XID parent; + gfx::AcceleratedWidget parent; bool file_operation; bool multiple_selection; }; @@ -106,7 +106,7 @@ class SelectFileDialogImplKDE : public SelectFileDialogImpl { void GetKDialogCommandLine(const std::string& type, const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, bool file_operation, bool multiple_selection, base::CommandLine* command_line); @@ -130,22 +130,22 @@ class SelectFileDialogImplKDE : public SelectFileDialogImpl { void CreateSelectFolderDialog(Type type, const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params); void CreateFileOpenDialog(const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params); void CreateMultiFileOpenDialog(const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params); void CreateSaveAsDialog(const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params); // Common function for OnSelectSingleFileDialogResponse and @@ -155,15 +155,15 @@ class SelectFileDialogImplKDE : public SelectFileDialogImpl { std::unique_ptr results); void OnSelectSingleFileDialogResponse( - XID parent, + gfx::AcceleratedWidget parent, void* params, std::unique_ptr results); void OnSelectMultiFileDialogResponse( - XID parent, + gfx::AcceleratedWidget parent, void* params, std::unique_ptr results); void OnSelectSingleFolderDialogResponse( - XID parent, + gfx::AcceleratedWidget parent, void* params, std::unique_ptr results); @@ -172,7 +172,7 @@ class SelectFileDialogImplKDE : public SelectFileDialogImpl { // The set of all parent windows for which we are currently running // dialogs. This should only be accessed on the UI thread. - std::set parents_; + std::set parents_; // A task runner for blocking pipe reads. scoped_refptr pipe_task_runner_; @@ -218,13 +218,13 @@ SelectFileDialogImplKDE::SelectFileDialogImplKDE( desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE5); } -SelectFileDialogImplKDE::~SelectFileDialogImplKDE() {} +SelectFileDialogImplKDE::~SelectFileDialogImplKDE() = default; bool SelectFileDialogImplKDE::IsRunning(gfx::NativeWindow parent_window) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (parent_window && parent_window->GetHost()) { - XID xid = parent_window->GetHost()->GetAcceleratedWidget(); - return parents_.find(xid) != parents_.end(); + auto window = parent_window->GetHost()->GetAcceleratedWidget(); + return parents_.find(window) != parents_.end(); } return false; @@ -243,13 +243,13 @@ void SelectFileDialogImplKDE::SelectFileImpl( DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); type_ = type; - XID window_xid = x11::None; + gfx::AcceleratedWidget window = gfx::kNullAcceleratedWidget; if (owning_window && owning_window->GetHost()) { // |owning_window| can be null when user right-clicks on a downloadable item // and chooses 'Open Link in New Tab' when 'Ask where to save each file // before downloading.' preference is turned on. (http://crbug.com/29213) - window_xid = owning_window->GetHost()->GetAcceleratedWidget(); - parents_.insert(window_xid); + window = owning_window->GetHost()->GetAcceleratedWidget(); + parents_.insert(window); } std::string title_string = base::UTF16ToUTF8(title); @@ -264,17 +264,17 @@ void SelectFileDialogImplKDE::SelectFileImpl( case SELECT_FOLDER: case SELECT_UPLOAD_FOLDER: case SELECT_EXISTING_FOLDER: - CreateSelectFolderDialog(type, title_string, default_path, window_xid, + CreateSelectFolderDialog(type, title_string, default_path, window, params); return; case SELECT_OPEN_FILE: - CreateFileOpenDialog(title_string, default_path, window_xid, params); + CreateFileOpenDialog(title_string, default_path, window, params); return; case SELECT_OPEN_MULTI_FILE: - CreateMultiFileOpenDialog(title_string, default_path, window_xid, params); + CreateMultiFileOpenDialog(title_string, default_path, window, params); return; case SELECT_SAVEAS_FILE: - CreateSaveAsDialog(title_string, default_path, window_xid, params); + CreateSaveAsDialog(title_string, default_path, window, params); return; case SELECT_NONE: NOTREACHED(); @@ -290,12 +290,11 @@ std::string SelectFileDialogImplKDE::GetMimeTypeFilterString() { DCHECK(pipe_task_runner_->RunsTasksInCurrentSequence()); // We need a filter set because the same mime type can appear multiple times. std::set filter_set; - for (size_t i = 0; i < file_types_.extensions.size(); ++i) { - for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { - if (!file_types_.extensions[i][j].empty()) { - std::string mime_type = - base::nix::GetFileMimeType(base::FilePath("name").ReplaceExtension( - file_types_.extensions[i][j])); + for (auto& extensions : file_types_.extensions) { + for (auto& extension : extensions) { + if (!extension.empty()) { + std::string mime_type = base::nix::GetFileMimeType( + base::FilePath("name").ReplaceExtension(extension)); filter_set.insert(mime_type); } } @@ -335,18 +334,18 @@ void SelectFileDialogImplKDE::GetKDialogCommandLine( const std::string& type, const std::string& title, const base::FilePath& path, - XID parent, + gfx::AcceleratedWidget parent, bool file_operation, bool multiple_selection, base::CommandLine* command_line) { CHECK(command_line); // Attach to the current Chrome window. - if (parent != x11::None) { + if (parent != gfx::kNullAcceleratedWidget) { command_line->AppendSwitchNative( desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE3 ? "--embed" : "--attach", - base::NumberToString(parent)); + base::NumberToString(static_cast(parent))); } // Set the correct title for the dialog. @@ -404,7 +403,7 @@ void SelectFileDialogImplKDE::CreateSelectFolderDialog( Type type, const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params) { int title_message_id = (type == SELECT_UPLOAD_FOLDER) ? IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE @@ -425,7 +424,7 @@ void SelectFileDialogImplKDE::CreateSelectFolderDialog( void SelectFileDialogImplKDE::CreateFileOpenDialog( const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params) { pipe_task_runner_->PostTaskAndReplyWithResult( FROM_HERE, @@ -442,7 +441,7 @@ void SelectFileDialogImplKDE::CreateFileOpenDialog( void SelectFileDialogImplKDE::CreateMultiFileOpenDialog( const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params) { pipe_task_runner_->PostTaskAndReplyWithResult( FROM_HERE, @@ -459,7 +458,7 @@ void SelectFileDialogImplKDE::CreateMultiFileOpenDialog( void SelectFileDialogImplKDE::CreateSaveAsDialog( const std::string& title, const base::FilePath& default_path, - XID parent, + gfx::AcceleratedWidget parent, void* params) { pipe_task_runner_->PostTaskAndReplyWithResult( FROM_HERE, @@ -496,7 +495,7 @@ void SelectFileDialogImplKDE::SelectSingleFileHelper( } void SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse( - XID parent, + gfx::AcceleratedWidget parent, void* params, std::unique_ptr results) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -505,7 +504,7 @@ void SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse( } void SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse( - XID parent, + gfx::AcceleratedWidget parent, void* params, std::unique_ptr results) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -514,7 +513,7 @@ void SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse( } void SelectFileDialogImplKDE::OnSelectMultiFileDialogResponse( - XID parent, + gfx::AcceleratedWidget parent, void* params, std::unique_ptr results) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); diff --git a/chromium/ui/gtk/x/gtk_event_loop_x11.cc b/chromium/ui/gtk/x/gtk_event_loop_x11.cc index aab1a9c3581..abda48cbf04 100644 --- a/chromium/ui/gtk/x/gtk_event_loop_x11.cc +++ b/chromium/ui/gtk/x/gtk_event_loop_x11.cc @@ -7,9 +7,12 @@ #include #include #include +#include +#include #include "base/memory/singleton.h" #include "ui/events/platform/x11/x11_event_source.h" +#include "ui/gfx/x/event.h" #include "ui/gfx/x/x11.h" namespace ui { @@ -66,26 +69,42 @@ void GtkEventLoopX11::ProcessGdkEventKey(const GdkEventKey& gdk_event_key) { // corresponding key event in the X event queue. So we have to handle this // case. ibus-gtk is used through gtk-immodule to support IMEs. - XEvent x_event; - x_event.xkey = {}; - x_event.xkey.type = - gdk_event_key.type == GDK_KEY_PRESS ? KeyPress : KeyRelease; - x_event.xkey.send_event = gdk_event_key.send_event; - x_event.xkey.display = gfx::GetXDisplay(); - x_event.xkey.window = GDK_WINDOW_XID(gdk_event_key.window); - x_event.xkey.root = DefaultRootWindow(x_event.xkey.display); - x_event.xkey.time = gdk_event_key.time; - x_event.xkey.keycode = gdk_event_key.hardware_keycode; - x_event.xkey.same_screen = true; - x_event.xkey.state = + auto* conn = x11::Connection::Get(); + XDisplay* display = conn->display(); + + xcb_generic_event_t generic_event; + memset(&generic_event, 0, sizeof(generic_event)); + auto* key_event = reinterpret_cast(&generic_event); + key_event->response_type = gdk_event_key.type == GDK_KEY_PRESS + ? x11::KeyEvent::Press + : x11::KeyEvent::Release; + if (gdk_event_key.send_event) + key_event->response_type |= x11::kSendEventMask; + key_event->event = GDK_WINDOW_XID(gdk_event_key.window); + key_event->root = DefaultRootWindow(display); + key_event->time = gdk_event_key.time; + key_event->detail = gdk_event_key.hardware_keycode; + key_event->same_screen = true; + + x11::Event event(&generic_event, conn, false); + + // The key state is 16 bits on the wire, but ibus-gtk adds additional flags + // that may be outside this range, so set the state after conversion from + // the wire format. + // TODO(https://crbug.com/1066670): Add a test to ensure this subtle logic + // doesn't regress after all X11 event code is refactored from using Xlib to + // XProto. + int state = BuildXkbStateFromGdkEvent(gdk_event_key.state, gdk_event_key.group); + event.xlib_event().xkey.state = state; + event.As()->state = static_cast(state); // We want to process the gtk event; mapped to an X11 event immediately // otherwise if we put it back on the queue we may get items out of order. if (ui::X11EventSource* x11_source = ui::X11EventSource::GetInstance()) - x11_source->DispatchXEventNow(&x_event); + x11_source->DispatchXEvent(&event); else - XPutBackEvent(x_event.xkey.display, &x_event); + conn->events().push_front(std::move(event)); } } // namespace ui diff --git a/chromium/ui/gtk/x/gtk_ui_delegate_x11.cc b/chromium/ui/gtk/x/gtk_ui_delegate_x11.cc index 8967d4af8ac..8ae0f44fe54 100644 --- a/chromium/ui/gtk/x/gtk_ui_delegate_x11.cc +++ b/chromium/ui/gtk/x/gtk_ui_delegate_x11.cc @@ -33,17 +33,20 @@ GdkKeymap* GtkUiDelegateX11::GetGdkKeymap() { GdkWindow* GtkUiDelegateX11::GetGdkWindow(gfx::AcceleratedWidget window_id) { GdkDisplay* display = GetGdkDisplay(); - GdkWindow* gdk_window = gdk_x11_window_lookup_for_display(display, window_id); + GdkWindow* gdk_window = gdk_x11_window_lookup_for_display( + display, static_cast(window_id)); if (gdk_window) g_object_ref(gdk_window); else - gdk_window = gdk_x11_window_foreign_new_for_display(display, window_id); + gdk_window = gdk_x11_window_foreign_new_for_display( + display, static_cast(window_id)); return gdk_window; } bool GtkUiDelegateX11::SetGdkWindowTransientFor(GdkWindow* window, gfx::AcceleratedWidget parent) { - XSetTransientForHint(xdisplay_, GDK_WINDOW_XID(window), parent); + XSetTransientForHint(xdisplay_, GDK_WINDOW_XID(window), + static_cast(parent)); return true; } -- cgit v1.2.1