Commit 3a01b73f authored by mukai@chromium.org's avatar mukai@chromium.org

Sets transient for PrintDialogGtk2

Moves the transient parent utilities to gtk2_util and makes both
dialogs use it.

This is a reland of r259318 with a fix of test failures.

BUG=334331
TBR=erg@chromium.org
TEST=manually

Review URL: https://codereview.chromium.org/221813010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@261473 0039d316-1c4b-4281-b951-d872f2087c98
parent d16b2e0a
......@@ -4,11 +4,15 @@
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include "base/command_line.h"
#include "base/environment.h"
#include "base/memory/scoped_ptr.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
......@@ -16,6 +20,8 @@
namespace {
const char kAuraTransientParent[] = "aura-transient-parent";
void CommonInitFromCommandLine(const CommandLine& command_line,
void (*init_func)(gint*, gchar***)) {
const std::vector<std::string>& args = command_line.argv();
......@@ -97,4 +103,30 @@ int EventFlagsFromGdkState(guint state) {
return flags;
}
// Set |dialog| as transient for |parent|, which will keep it on top and center
// it above |parent|.
void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) {
gtk_widget_realize(dialog);
GdkWindow* gdk_window = gtk_widget_get_window(dialog);
// TODO(erg): Check to make sure we're using X11 if wayland or some other
// display server ever happens. Otherwise, this will crash.
XSetTransientForHint(GDK_WINDOW_XDISPLAY(gdk_window),
GDK_WINDOW_XID(gdk_window),
parent->GetHost()->GetAcceleratedWidget());
// We also set the |parent| as a property of |dialog|, so that we can unlink
// the two later.
g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, parent);
}
aura::Window* GetAuraTransientParent(GtkWidget* dialog) {
return reinterpret_cast<aura::Window*>(
g_object_get_data(G_OBJECT(dialog), kAuraTransientParent));
}
void ClearAuraTransientParent(GtkWidget* dialog) {
g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, NULL);
}
} // namespace libgtk2ui
......@@ -10,6 +10,10 @@
class SkBitmap;
namespace aura {
class Window;
}
namespace base {
class CommandLine;
class Environment;
......@@ -39,6 +43,16 @@ GdkModifierType GetGdkModifierForAccelerator(
// Translates event flags into plaform independent event flags.
int EventFlagsFromGdkState(guint state);
// Sets |dialog| as transient for |parent|, which will keep it on top and center
// it above |parent|.
void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent);
// Gets the transient parent aura window for |dialog|.
aura::Window* GetAuraTransientParent(GtkWidget* dialog);
// Clears the transient parent for |dialog|.
void ClearAuraTransientParent(GtkWidget* dialog);
} // namespace libgtk2ui
#endif // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_UTIL_H_
......@@ -17,10 +17,12 @@
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include "chrome/browser/ui/libgtk2ui/printing_gtk2_util.h"
#include "printing/metafile.h"
#include "printing/print_job_constants.h"
#include "printing/print_settings.h"
#include "ui/aura/window.h"
using content::BrowserThread;
using printing::PageRanges;
......@@ -136,6 +138,11 @@ PrintDialogGtk2::~PrintDialogGtk2() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (dialog_) {
aura::Window* parent = libgtk2ui::GetAuraTransientParent(dialog_);
if (parent) {
parent->RemoveObserver(this);
libgtk2ui::ClearAuraTransientParent(dialog_);
}
gtk_widget_destroy(dialog_);
dialog_ = NULL;
}
......@@ -234,6 +241,8 @@ void PrintDialogGtk2::ShowDialog(
// TODO(mukai): take care of parent as select_file_dialog_impl_gtk2.
dialog_ = gtk_print_unix_dialog_new(NULL, NULL);
libgtk2ui::SetGtkTransientForAura(dialog_, parent_view);
parent_view->AddObserver(this);
g_signal_connect(dialog_, "delete-event",
G_CALLBACK(gtk_widget_hide_on_delete), NULL);
......@@ -432,3 +441,11 @@ void PrintDialogGtk2::InitPrintSettings(PrintSettings* settings) {
InitPrintSettingsGtk(gtk_settings_, page_setup_, settings);
context_->InitWithSettings(*settings);
}
void PrintDialogGtk2::OnWindowDestroying(aura::Window* window) {
DCHECK_EQ(libgtk2ui::GetAuraTransientParent(dialog_), window);
libgtk2ui::ClearAuraTransientParent(dialog_);
window->RemoveObserver(this);
Release();
}
......@@ -16,6 +16,7 @@
#include "content/public/browser/browser_thread.h"
#include "printing/print_dialog_gtk_interface.h"
#include "printing/printing_context_linux.h"
#include "ui/aura/window_observer.h"
namespace printing {
class Metafile;
......@@ -28,7 +29,8 @@ using printing::PrintingContextLinux;
class PrintDialogGtk2
: public printing::PrintDialogGtkInterface,
public base::RefCountedThreadSafe<
PrintDialogGtk2, content::BrowserThread::DeleteOnUIThread> {
PrintDialogGtk2, content::BrowserThread::DeleteOnUIThread>,
public aura::WindowObserver {
public:
// Creates and returns a print dialog.
static printing::PrintDialogGtkInterface* CreatePrintDialog(
......@@ -70,6 +72,9 @@ class PrintDialogGtk2
// |settings|.
void InitPrintSettings(printing::PrintSettings* settings);
// aura::WindowObserver implementation.
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
// Printing dialog callback.
PrintingContextLinux::PrintSettingsCallback callback_;
PrintingContextLinux* context_;
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <map>
#include <set>
......@@ -21,34 +19,15 @@
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_signal.h"
#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h"
#include "grit/ui_strings.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/shell_dialogs/select_file_dialog.h"
namespace {
const char kAuraTransientParent[] = "aura-transient-parent";
// Set |dialog| as transient for |parent|, which will keep it on top and center
// it above |parent|.
void SetGtkTransientForAura(GtkWidget* dialog, aura::Window* parent) {
gtk_widget_realize(dialog);
GdkWindow* gdk_window = gtk_widget_get_window(dialog);
// TODO(erg): Check to make sure we're using X11 if wayland or some other
// display server ever happens. Otherwise, this will crash.
XSetTransientForHint(GDK_WINDOW_XDISPLAY(gdk_window),
GDK_WINDOW_XID(gdk_window),
parent->GetHost()->GetAcceleratedWidget());
// We also set the |parent| as a property of |dialog|, so that we can unlink
// the two later.
g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, parent);
}
// Makes sure that .jpg also shows .JPG.
gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info,
std::string* file_extension) {
......@@ -208,10 +187,9 @@ void SelectFileDialogImplGTK::OnWindowDestroying(aura::Window* window) {
// Remove the |parent| property associated with the |dialog|.
for (std::set<GtkWidget*>::iterator it = dialogs_.begin();
it != dialogs_.end(); ++it) {
aura::Window* parent = reinterpret_cast<aura::Window*>(
g_object_get_data(G_OBJECT(*it), kAuraTransientParent));
aura::Window* parent = GetAuraTransientParent(*it);
if (parent == window)
g_object_set_data(G_OBJECT(*it), kAuraTransientParent, NULL);
ClearAuraTransientParent(*it);
}
std::set<aura::Window*>::iterator iter = parents_.find(window);
......@@ -525,8 +503,7 @@ void SelectFileDialogImplGTK::FileDialogDestroyed(GtkWidget* dialog) {
// windows got destroyed, or 2) when the parent tab has been opened by
// 'Open Link in New Tab' context menu on a downloadable item and
// the tab has no content (see the comment in SelectFile as well).
aura::Window* parent = reinterpret_cast<aura::Window*>(
g_object_get_data(G_OBJECT(dialog), kAuraTransientParent));
aura::Window* parent = GetAuraTransientParent(dialog);
if (!parent)
return;
std::set<aura::Window*>::iterator iter = parents_.find(parent);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment