]> git.sesse.net Git - casparcg/blobdiff - dependencies64/cef/linux/tests/ceftests/views/window_unittest.cc
Upgrade CEF to 3.3029.1611.g44e39a8 / Chromium 58.0.3029.81.
[casparcg] / dependencies64 / cef / linux / tests / ceftests / views / window_unittest.cc
diff --git a/dependencies64/cef/linux/tests/ceftests/views/window_unittest.cc b/dependencies64/cef/linux/tests/ceftests/views/window_unittest.cc
new file mode 100644 (file)
index 0000000..d8d70a3
--- /dev/null
@@ -0,0 +1,496 @@
+// Copyright (c) 2016 The Chromium Embedded Framework 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 "include/base/cef_bind.h"
+#include "include/views/cef_box_layout.h"
+#include "include/views/cef_panel.h"
+#include "include/views/cef_layout.h"
+#include "include/wrapper/cef_closure_task.h"
+#include "tests/ceftests/image_util.h"
+#include "tests/ceftests/thread_helper.h"
+#include "tests/ceftests/views/test_window_delegate.h"
+#include "tests/gtest/include/gtest/gtest.h"
+
+#define WINDOW_TEST_ASYNC(name) UI_THREAD_TEST_ASYNC(ViewsWindowTest, name)
+
+#if !defined(OS_WIN)
+#define VK_MENU   0x12  // ALT key.
+#endif
+
+namespace {
+
+// Window state change delay in MS.
+const int kStateDelayMS = 200;
+
+const int kWSize = TestWindowDelegate::kWSize;
+
+// Test that |expected| and |actual| are within |allowed_deviance| of each
+// other.
+void ExpectCloseRects(const CefRect& expected,
+                      const CefRect& actual,
+                      int allowed_deviance) {
+  EXPECT_LE(abs(expected.x - actual.x), allowed_deviance);
+  EXPECT_LE(abs(expected.y - actual.y), allowed_deviance);
+  EXPECT_LE(abs(expected.width - actual.width), allowed_deviance);
+  EXPECT_LE(abs(expected.height - actual.height), allowed_deviance);
+}
+
+void WindowCreateImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void WindowCreateFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.frameless = true;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void RunWindowShowHide(CefRefPtr<CefWindow> window) {
+  EXPECT_FALSE(window->IsVisible());
+  EXPECT_FALSE(window->IsDrawn());
+  window->Show();
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+  window->Hide();
+  EXPECT_FALSE(window->IsVisible());
+  EXPECT_FALSE(window->IsDrawn());
+}
+
+void WindowShowHideImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowShowHide);
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void WindowShowHideFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowShowHide);
+  config.frameless = true;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+const int kWPanel1ID = 1;
+const int kWPanel2ID = 2;
+
+void CreateBoxLayout(CefRefPtr<CefWindow> parent) {
+  CefRefPtr<CefPanel> panel_child1 = CefPanel::CreatePanel(nullptr);
+  panel_child1->SetID(kWPanel1ID);
+  panel_child1->SetBackgroundColor(CefColorSetARGB(255, 0, 0, 255));
+  EXPECT_TRUE(panel_child1->IsVisible());
+  EXPECT_FALSE(panel_child1->IsDrawn());
+
+  CefRefPtr<CefPanel> panel_child2 = CefPanel::CreatePanel(nullptr);
+  panel_child2->SetID(kWPanel2ID);
+  panel_child2->SetBackgroundColor(CefColorSetARGB(255, 0, 255, 0));
+  EXPECT_TRUE(panel_child2->IsVisible());
+  EXPECT_FALSE(panel_child2->IsDrawn());
+  // Set to BoxLayout. Default layout is vertical with children stretched along
+  // the horizontal axis.
+  CefBoxLayoutSettings settings;
+  parent->SetToBoxLayout(settings);
+
+  parent->AddChildView(panel_child1);
+  parent->AddChildView(panel_child2);
+
+  // IsDrawn() returns true because the Panels now have a RootView from the
+  // Window.
+  EXPECT_TRUE(panel_child1->IsDrawn());
+  EXPECT_TRUE(panel_child1->IsDrawn());
+
+  // Stretch children equally along the vertical axis using flex.
+  CefRefPtr<CefBoxLayout> layout = parent->GetLayout()->AsBoxLayout();
+  layout->SetFlexForView(panel_child1, 1);
+  layout->SetFlexForView(panel_child2, 1);
+
+  // Force layout.
+  parent->Layout();
+
+  // The children should each take up 50% of the client area.
+  ExpectCloseRects(CefRect(0, 0, kWSize, kWSize / 2),
+                   panel_child1->GetBounds(), 1);
+  ExpectCloseRects(CefRect(0, kWSize / 2, kWSize, kWSize / 2),
+                   panel_child2->GetBounds(), 1);
+}
+
+void RunWindowLayoutAndCoords(CefRefPtr<CefWindow> window) {
+  CreateBoxLayout(window);
+
+  CefRefPtr<CefView> view1 = window->GetViewForID(kWPanel1ID);
+  EXPECT_TRUE(view1.get());
+  CefRefPtr<CefView> view2 = window->GetViewForID(kWPanel2ID);
+  EXPECT_TRUE(view2.get());
+
+  window->Show();
+
+  CefRect client_bounds_in_screen = window->GetClientAreaBoundsInScreen();
+  CefPoint point;
+
+  // Test view to screen coordinate conversions.
+  point = CefPoint(0, 0);
+  EXPECT_TRUE(view1->ConvertPointToScreen(point));
+  EXPECT_EQ(CefPoint(client_bounds_in_screen.x, client_bounds_in_screen.y),
+            point);
+  point = CefPoint(0, 0);
+  EXPECT_TRUE(view2->ConvertPointToScreen(point));
+  EXPECT_EQ(CefPoint(client_bounds_in_screen.x,
+                     client_bounds_in_screen.y + kWSize / 2),
+            point);
+
+  // Test view from screen coordinate conversions.
+  point = CefPoint(client_bounds_in_screen.x, client_bounds_in_screen.y);
+  EXPECT_TRUE(view1->ConvertPointFromScreen(point));
+  EXPECT_EQ(CefPoint(0, 0), point);
+  point = CefPoint(client_bounds_in_screen.x,
+                   client_bounds_in_screen.y + kWSize / 2);
+  EXPECT_TRUE(view2->ConvertPointFromScreen(point));
+  EXPECT_EQ(CefPoint(0, 0), point);
+
+  // Test view to window coordinate conversions.
+  point = CefPoint(0, 0);
+  EXPECT_TRUE(view1->ConvertPointToWindow(point));
+  EXPECT_EQ(CefPoint(0, 0), point);
+  point = CefPoint(0, 0);
+  EXPECT_TRUE(view2->ConvertPointToWindow(point));
+  EXPECT_EQ(CefPoint(0, kWSize / 2), point);
+
+  // Test view from window coordinate conversions.
+  point = CefPoint(0, 0);
+  EXPECT_TRUE(view1->ConvertPointFromWindow(point));
+  EXPECT_EQ(CefPoint(0, 0), point);
+  point = CefPoint(0, kWSize / 2);
+  EXPECT_TRUE(view2->ConvertPointFromWindow(point));
+  EXPECT_EQ(CefPoint(0, 0), point);
+
+  // Test view to view coordinate conversions.
+  point = CefPoint(0, 0);
+  EXPECT_TRUE(view1->ConvertPointToView(view2, point));
+  EXPECT_EQ(CefPoint(0, -kWSize / 2), point);
+  point = CefPoint(0, 0);
+  EXPECT_TRUE(view2->ConvertPointToView(view1, point));
+  EXPECT_EQ(CefPoint(0, kWSize / 2), point);
+
+  // Test view from view coordinate conversions.
+  point = CefPoint(0, -kWSize / 2);
+  EXPECT_TRUE(view1->ConvertPointFromView(view2, point));
+  EXPECT_EQ(CefPoint(0, 0), point);
+  point = CefPoint(0, kWSize / 2);
+  EXPECT_TRUE(view2->ConvertPointFromView(view1, point));
+  EXPECT_EQ(CefPoint(0, 0), point);
+
+  CefRefPtr<CefDisplay> display = window->GetDisplay();
+  EXPECT_TRUE(display.get());
+
+  // We don't know what the pixel values will be, but they should be reversable.
+  point = CefPoint(client_bounds_in_screen.x, client_bounds_in_screen.y);
+  display->ConvertPointToPixels(point);
+  display->ConvertPointFromPixels(point);
+  EXPECT_EQ(CefPoint(client_bounds_in_screen.x, client_bounds_in_screen.y),
+            point);
+}
+
+void WindowLayoutAndCoordsImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowLayoutAndCoords);
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void WindowLayoutAndCoordsFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowLayoutAndCoords);
+  config.frameless = true;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void VerifyRestore(CefRefPtr<CefWindow> window) {
+  EXPECT_FALSE(window->IsMinimized());
+  EXPECT_FALSE(window->IsMaximized());
+  EXPECT_FALSE(window->IsFullscreen());
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  // End the test by closing the Window.
+  window->Close();
+}
+
+void VerifyMaximize(CefRefPtr<CefWindow> window) {
+  EXPECT_FALSE(window->IsMinimized());
+  EXPECT_TRUE(window->IsMaximized());
+  EXPECT_FALSE(window->IsFullscreen());
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  window->Restore();
+  CefPostDelayedTask(TID_UI, base::Bind(VerifyRestore, window), kStateDelayMS);
+}
+
+void RunWindowMaximize(CefRefPtr<CefWindow> window) {
+  CreateBoxLayout(window);
+  window->Show();
+  EXPECT_FALSE(window->IsMinimized());
+  EXPECT_FALSE(window->IsMaximized());
+  EXPECT_FALSE(window->IsFullscreen());
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  window->Maximize();
+  CefPostDelayedTask(TID_UI, base::Bind(VerifyMaximize, window), kStateDelayMS);
+}
+
+void WindowMaximizeImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowMaximize);
+  config.close_window = false;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void WindowMaximizeFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowMaximize);
+  config.frameless = true;
+  config.close_window = false;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void VerifyMinimize(CefRefPtr<CefWindow> window) {
+  EXPECT_TRUE(window->IsMinimized());
+  EXPECT_FALSE(window->IsMaximized());
+  EXPECT_FALSE(window->IsFullscreen());
+
+  // This result is a bit unexpected, but I guess the platform considers a
+  // window to be visible even when it's minimized.
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  window->Restore();
+  CefPostDelayedTask(TID_UI, base::Bind(VerifyRestore, window), kStateDelayMS);
+}
+
+void RunWindowMinimize(CefRefPtr<CefWindow> window) {
+  CreateBoxLayout(window);
+  window->Show();
+  EXPECT_FALSE(window->IsMinimized());
+  EXPECT_FALSE(window->IsMaximized());
+  EXPECT_FALSE(window->IsFullscreen());
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  window->Minimize();
+  CefPostDelayedTask(TID_UI, base::Bind(VerifyMinimize, window), kStateDelayMS);
+}
+
+void WindowMinimizeImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowMinimize);
+  config.close_window = false;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void WindowMinimizeFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowMinimize);
+  config.frameless = true;
+  config.close_window = false;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void VerifyFullscreenExit(CefRefPtr<CefWindow> window) {
+  EXPECT_FALSE(window->IsMinimized());
+  EXPECT_FALSE(window->IsMaximized());
+  EXPECT_FALSE(window->IsFullscreen());
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  // End the test by closing the Window.
+  window->Close();
+}
+
+void VerifyFullscreen(CefRefPtr<CefWindow> window) {
+  EXPECT_FALSE(window->IsMinimized());
+  EXPECT_FALSE(window->IsMaximized());
+  EXPECT_TRUE(window->IsFullscreen());
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  window->SetFullscreen(false);
+  CefPostDelayedTask(TID_UI, base::Bind(VerifyFullscreenExit, window),
+                     kStateDelayMS);
+}
+
+void RunWindowFullscreen(CefRefPtr<CefWindow> window) {
+  CreateBoxLayout(window);
+  window->Show();
+  EXPECT_FALSE(window->IsMinimized());
+  EXPECT_FALSE(window->IsMaximized());
+  EXPECT_FALSE(window->IsFullscreen());
+  EXPECT_TRUE(window->IsVisible());
+  EXPECT_TRUE(window->IsDrawn());
+
+  window->SetFullscreen(true);
+  CefPostDelayedTask(TID_UI, base::Bind(VerifyFullscreen, window),
+                     kStateDelayMS);
+}
+
+void WindowFullscreenImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowFullscreen);
+  config.close_window = false;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void WindowFullscreenFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowFullscreen);
+  config.frameless = true;
+  config.close_window = false;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void RunWindowIcon(CefRefPtr<CefWindow> window) {
+  CefRefPtr<CefImage> image = CefImage::CreateImage();
+  image_util::LoadIconImage(image, 1.0);
+  image_util::LoadIconImage(image, 2.0);
+
+  EXPECT_FALSE(window->GetWindowIcon().get());
+  window->SetWindowIcon(image);
+  EXPECT_TRUE(image->IsSame(window->GetWindowIcon()));
+
+  EXPECT_FALSE(window->GetWindowAppIcon().get());
+  window->SetWindowAppIcon(image);
+  EXPECT_TRUE(image->IsSame(window->GetWindowAppIcon()));
+
+  window->Show();
+}
+
+void WindowIconImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowIcon);
+  TestWindowDelegate::RunTest(event, config);
+}
+
+void WindowIconFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowIcon);
+  config.frameless = true;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+const int kChar = 'A';
+const int kCloseWindowId = 2;
+bool got_accelerator;
+int got_key_event_alt_count;
+bool got_key_event_char;
+
+void TriggerAccelerator(CefRefPtr<CefWindow> window) {
+  window->SendKeyPress(kChar, EVENTFLAG_ALT_DOWN);
+}
+
+bool OnKeyEvent(CefRefPtr<CefWindow> window, const CefKeyEvent& event) {
+  if (event.type != KEYEVENT_RAWKEYDOWN)
+    return false;
+
+  if (event.windows_key_code == VK_MENU) {
+    // First we get the ALT key press in all cases.
+    EXPECT_FALSE(got_key_event_char);
+    if (got_key_event_alt_count == 0)
+      EXPECT_FALSE(got_accelerator);
+    else
+      EXPECT_TRUE(got_accelerator);
+
+    EXPECT_EQ(event.modifiers, EVENTFLAG_ALT_DOWN);
+    got_key_event_alt_count++;
+  } else if (event.windows_key_code == kChar) {
+    // Then we get the char key press with the ALT modifier if the accelerator
+    // isn't registered.
+    EXPECT_TRUE(got_accelerator);
+    EXPECT_EQ(got_key_event_alt_count, 2);
+    EXPECT_FALSE(got_key_event_char);
+
+    EXPECT_EQ(event.modifiers, EVENTFLAG_ALT_DOWN);
+    got_key_event_char = true;
+
+    // Call this method just to make sure it doesn't crash.
+    window->RemoveAllAccelerators();
+
+    // End the test by closing the Window.
+    window->Close();
+
+    return true;
+  }
+
+  return false;
+}
+
+bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) {
+  EXPECT_FALSE(got_accelerator);
+  EXPECT_EQ(got_key_event_alt_count, 1);
+  EXPECT_FALSE(got_key_event_char);
+
+  EXPECT_EQ(kCloseWindowId, command_id);
+  got_accelerator = true;
+
+  // Remove the accelerator.
+  window->RemoveAccelerator(kCloseWindowId);
+
+  // Now send the event without the accelerator registered. Should result in a
+  // call to OnKeyEvent.
+  TriggerAccelerator(window);
+
+  return true;
+}
+
+void RunWindowAccelerator(CefRefPtr<CefWindow> window) {
+  window->SetAccelerator(kCloseWindowId, kChar, false, false, true);
+  window->Show();
+
+  CefPostDelayedTask(TID_UI, base::Bind(TriggerAccelerator, window),
+                     kStateDelayMS);
+}
+
+void VerifyWindowAccelerator(CefRefPtr<CefWindow> window) {
+  EXPECT_TRUE(got_accelerator);
+  EXPECT_EQ(got_key_event_alt_count, 2);
+  EXPECT_TRUE(got_key_event_char);
+}
+
+// Expected order of events:
+// 1. OnKeyEvent for ALT key press.
+// 2. OnAccelerator for ALT+Char key press (with accelerator registered).
+// 3. OnKeyEvent for ALT key press.
+// 4. OnKeyEvent for ALT+Char key press (without accelerator registered).
+void WindowAcceleratorImpl(CefRefPtr<CefWaitableEvent> event) {
+  got_accelerator = false;
+  got_key_event_alt_count = 0;
+  got_key_event_char = false;
+
+  TestWindowDelegate::Config config;
+  config.on_window_created = base::Bind(RunWindowAccelerator);
+  config.on_window_destroyed = base::Bind(VerifyWindowAccelerator);
+  config.on_accelerator = base::Bind(OnAccelerator);
+  config.on_key_event = base::Bind(OnKeyEvent);
+  config.close_window = false;
+  TestWindowDelegate::RunTest(event, config);
+}
+
+}  // namespace
+
+// Test window functionality. This is primarily to exercise exposed CEF APIs
+// and is not intended to comprehensively test window-related behavior (which
+// we presume that Chromium is testing).
+WINDOW_TEST_ASYNC(WindowCreate);
+WINDOW_TEST_ASYNC(WindowCreateFrameless);
+WINDOW_TEST_ASYNC(WindowShowHide);
+WINDOW_TEST_ASYNC(WindowShowHideFrameless);
+WINDOW_TEST_ASYNC(WindowLayoutAndCoords);
+WINDOW_TEST_ASYNC(WindowLayoutAndCoordsFrameless);
+WINDOW_TEST_ASYNC(WindowMaximize);
+WINDOW_TEST_ASYNC(WindowMaximizeFrameless);
+WINDOW_TEST_ASYNC(WindowMinimize);
+WINDOW_TEST_ASYNC(WindowMinimizeFrameless);
+WINDOW_TEST_ASYNC(WindowFullscreen);
+WINDOW_TEST_ASYNC(WindowFullscreenFrameless);
+WINDOW_TEST_ASYNC(WindowIcon);
+WINDOW_TEST_ASYNC(WindowIconFrameless);
+WINDOW_TEST_ASYNC(WindowAccelerator);