summaryrefslogtreecommitdiffstats
path: root/ui/views
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 02:09:39 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-28 02:09:39 +0000
commitde4cf1c640fe72d851e5059fc18ef41564211007 (patch)
tree642538f20fc94e350085def194180fc3ab5457bd /ui/views
parent2329bfc7e24312230f78f7e37eab11596f3ab243 (diff)
downloadchromium_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.cc38
-rw-r--r--ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h4
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()?