diff options
author | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 02:09:39 +0000 |
---|---|---|
committer | erg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 02:09:39 +0000 |
commit | de4cf1c640fe72d851e5059fc18ef41564211007 (patch) | |
tree | 642538f20fc94e350085def194180fc3ab5457bd /ui/views | |
parent | 2329bfc7e24312230f78f7e37eab11596f3ab243 (diff) | |
download | chromium_src-de4cf1c640fe72d851e5059fc18ef41564211007.zip chromium_src-de4cf1c640fe72d851e5059fc18ef41564211007.tar.gz chromium_src-de4cf1c640fe72d851e5059fc18ef41564211007.tar.bz2 |
linux_aura: Don't create a drag window when given a transparent image.
BUG=330103
Review URL: https://codereview.chromium.org/169433006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254015 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views')
-rw-r--r-- | ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc | 38 | ||||
-rw-r--r-- | ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h | 4 |
2 files changed, 38 insertions, 4 deletions
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc index e8f48a0..b2a7b1b 100644 --- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc +++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc @@ -8,10 +8,10 @@ // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. #undef RootWindow -#include "base/debug/stack_trace.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_pump_x11.h" #include "base/run_loop.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "ui/aura/env.h" #include "ui/aura/window.h" #include "ui/aura/window_event_dispatcher.h" @@ -27,6 +27,10 @@ namespace views { namespace { +// The minimum alpha before we declare a pixel transparent when searching in +// our source image. +const int kMinAlpha = 32; + class ScopedCapturer { public: explicit ScopedCapturer(aura::WindowTreeHost* host) @@ -108,8 +112,8 @@ bool X11WholeScreenMoveLoop::RunMoveLoop(aura::Window* source, XDisplay* display = gfx::GetXDisplay(); grab_input_window_ = CreateDragInputWindow(display); - if (!drag_image_.isNull()) - CreateDragImageWindow(); + if (!drag_image_.isNull() && CheckIfIconValid()) + CreateDragImageWindow(); base::MessagePumpX11::Current()->AddDispatcherForWindow( this, grab_input_window_); // Releasing ScopedCapturer ensures that any other instance of @@ -249,11 +253,37 @@ void X11WholeScreenMoveLoop::CreateDragImageWindow() { image->SetImage(drag_image_); image->SetBounds(0, 0, drag_image_.width(), drag_image_.height()); widget->SetContentsView(image); - widget->Show(); widget->GetNativeWindow()->layer()->SetFillsBoundsOpaquely(false); drag_widget_.reset(widget); } +bool X11WholeScreenMoveLoop::CheckIfIconValid() { + // TODO(erg): I've tried at least five different strategies for trying to + // build a mask based off the alpha channel. While all of them have worked, + // none of them have been performant and introduced multiple second + // delays. (I spent a day getting a rectangle segmentation algorithm polished + // here...and then found that even through I had the rectangle extraction + // down to mere milliseconds, SkRegion still fell over on the number of + // rectangles.) + // + // Creating a mask here near instantaneously should be possible, as GTK does + // it, but I've blown days on this and I'm punting now. + + const SkBitmap* in_bitmap = drag_image_.bitmap(); + SkAutoLockPixels in_lock(*in_bitmap); + for (int y = 0; y < in_bitmap->height(); ++y) { + uint32* in_row = in_bitmap->getAddr32(0, y); + + for (int x = 0; x < in_bitmap->width(); ++x) { + char value = SkColorGetA(in_row[x]) > kMinAlpha; + if (value) + return true; + } + } + + return false; +} + } // namespace views diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h index e2e712d..90417b4 100644 --- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h +++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h @@ -58,6 +58,10 @@ class X11WholeScreenMoveLoop : public base::MessagePumpDispatcher { // Creates a window to show the drag image during the drag. void CreateDragImageWindow(); + // Checks to see if |in_image| is an image that has any visible regions + // (defined as having a pixel with alpha > 32). If so, return true. + bool CheckIfIconValid(); + X11WholeScreenMoveLoopDelegate* delegate_; // Are we running a nested message loop from RunMoveLoop()? |