summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ppapi/api/dev/ppb_fullscreen_dev.idl10
-rw-r--r--ppapi/c/dev/ppb_fullscreen_dev.h12
-rw-r--r--ppapi/native_client/tests/ppapi_browser/ppb_fullscreen/ppapi_ppb_fullscreen.cc26
-rw-r--r--ppapi/tests/test_fullscreen.cc16
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.cc99
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.h19
6 files changed, 139 insertions, 43 deletions
diff --git a/ppapi/api/dev/ppb_fullscreen_dev.idl b/ppapi/api/dev/ppb_fullscreen_dev.idl
index 028cda6..0fd6373 100644
--- a/ppapi/api/dev/ppb_fullscreen_dev.idl
+++ b/ppapi/api/dev/ppb_fullscreen_dev.idl
@@ -27,14 +27,12 @@ interface PPB_Fullscreen_Dev {
* will execute as if the resource was off-screen. The transition to and from
* fullscreen is asynchronous. During the transition, IsFullscreen will
* return the original value, and no 2D or 3D device can be bound.
- * The transition ends at the next DidChangeView.
+ * The transition ends at DidChangeView when IsFullscreen returns the new
+ * value. You might receive other DidChangeView calls while in
+ * transition.
*
* The transition to fullscreen can only occur while the browser is
- * processing a user gesture, even if PP_TRUE is returned. Note that two
- * DidChangeView calls will happen when switching to fullscreen:
- * one for moving the plugin to the middle of the window and one for
- * stretching the window placing the plugin in the middle of the screen.
- * Plugin size will not be affected.
+ * processing a user gesture, even if PP_TRUE is returned.
*/
PP_Bool SetFullscreen(
[in] PP_Instance instance,
diff --git a/ppapi/c/dev/ppb_fullscreen_dev.h b/ppapi/c/dev/ppb_fullscreen_dev.h
index bae1497..5022c2a 100644
--- a/ppapi/c/dev/ppb_fullscreen_dev.h
+++ b/ppapi/c/dev/ppb_fullscreen_dev.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From dev/ppb_fullscreen_dev.idl modified Mon Sep 26 15:06:40 2011. */
+/* From dev/ppb_fullscreen_dev.idl modified Tue Oct 11 15:45:41 2011. */
#ifndef PPAPI_C_DEV_PPB_FULLSCREEN_DEV_H_
#define PPAPI_C_DEV_PPB_FULLSCREEN_DEV_H_
@@ -40,14 +40,12 @@ struct PPB_Fullscreen_Dev {
* will execute as if the resource was off-screen. The transition to and from
* fullscreen is asynchronous. During the transition, IsFullscreen will
* return the original value, and no 2D or 3D device can be bound.
- * The transition ends at the next DidChangeView.
+ * The transition ends at DidChangeView when IsFullscreen returns the new
+ * value. You might receive other DidChangeView calls while in
+ * transition.
*
* The transition to fullscreen can only occur while the browser is
- * processing a user gesture, even if PP_TRUE is returned. Note that two
- * DidChangeView calls will happen when switching to fullscreen:
- * one for moving the plugin to the middle of the window and one for
- * stretching the window placing the plugin in the middle of the screen.
- * Plugin size will not be affected.
+ * processing a user gesture, even if PP_TRUE is returned.
*/
PP_Bool (*SetFullscreen)(PP_Instance instance, PP_Bool fullscreen);
/**
diff --git a/ppapi/native_client/tests/ppapi_browser/ppb_fullscreen/ppapi_ppb_fullscreen.cc b/ppapi/native_client/tests/ppapi_browser/ppb_fullscreen/ppapi_ppb_fullscreen.cc
index 4a87752..333605e 100644
--- a/ppapi/native_client/tests/ppapi_browser/ppb_fullscreen/ppapi_ppb_fullscreen.cc
+++ b/ppapi/native_client/tests/ppapi_browser/ppb_fullscreen/ppapi_ppb_fullscreen.cc
@@ -221,11 +221,8 @@ bool HasMidScreen(const PP_Rect* position) {
}
// DidChangeView completes transition to/from fullscreen mode.
-// In fact, we get two of them when going to fullscreen, one when the plugin
-// is placed in the middle of the window and one when the window is resized,
-// placing the plugin in the middle of the screen.
-// The size of the plugin is not affected.
-bool g_saw_first_didchangeview = false;
+// The plugin is resized to the size of the screen.
+// NOTE: The number of DidChangeView calls for <object> might be different.
PP_Rect g_normal_position = PP_MakeRectFromXYWH(0, 0, 0, 0);
void DidChangeView(PP_Instance instance,
const struct PP_Rect* position,
@@ -247,22 +244,17 @@ void DidChangeView(PP_Instance instance,
}
const char* test = NULL;
- if (g_fullscreen_pending && !g_saw_first_didchangeview) {
- g_saw_first_didchangeview = true;
- EXPECT(PPBFullscreenDev()->IsFullscreen(pp_instance()) == PP_TRUE);
- EXPECT(IsSizeEqual(position->size, g_normal_position.size));
- // Wait for the 2nd DidChangeView.
- } else if (g_fullscreen_pending) {
+ PP_Size screen_size = GetScreenSize();
+ if (g_fullscreen_pending && PPBFullscreenDev()->IsFullscreen(pp_instance())) {
test = "TestSetFullscreenTrue";
g_fullscreen_pending = false;
- g_saw_first_didchangeview = false; // Reset.
- EXPECT(PPBFullscreenDev()->IsFullscreen(pp_instance()) == PP_TRUE);
- EXPECT(HasMidScreen(position));
- EXPECT(IsSizeEqual(position->size, g_normal_position.size));
- } else if (g_normal_pending) {
+ EXPECT(IsSizeEqual(position->size, screen_size));
+ // NOTE: we cannot reliably test for clip size being equal to the screen
+ // because it might be affected by JS console, info bars, etc.
+ } else if (g_normal_pending &&
+ !PPBFullscreenDev()->IsFullscreen(pp_instance())) {
test = "TestSetFullscreenFalse";
g_normal_pending = false;
- EXPECT(PPBFullscreenDev()->IsFullscreen(pp_instance()) == PP_FALSE);
EXPECT(IsRectEqual(*position, g_normal_position));
}
if (test != NULL) {
diff --git a/ppapi/tests/test_fullscreen.cc b/ppapi/tests/test_fullscreen.cc
index 95a0dd7..6963aaf 100644
--- a/ppapi/tests/test_fullscreen.cc
+++ b/ppapi/tests/test_fullscreen.cc
@@ -185,7 +185,11 @@ bool TestFullscreen::HandleInputEvent(const pp::InputEvent& event) {
// When going to fullscreen, two DidChangeView calls are generated:
// one for moving the plugin to the middle of window and one for stretching
// the window and placing the plugin in the middle of the screen.
-// Plugin size does not change.
+// WebKit does not change the plugin size, but Pepper does explicitly set
+// it to screen width and height when SetFullscreen(true) is called and
+// resets it back when ViewChanged is received indicating that we exited
+// fullscreen.
+// NOTE: The number of DidChangeView calls for <object> might be different.
void TestFullscreen::DidChangeView(const pp::Rect& position,
const pp::Rect& clip) {
if (normal_position_.IsEmpty())
@@ -195,8 +199,8 @@ void TestFullscreen::DidChangeView(const pp::Rect& position,
saw_first_fullscreen_didchangeview = true;
if (!screen_mode_.IsFullscreen())
FailFullscreenTest("DidChangeView1 is not in fullscreen");
- if (position.size() != normal_position_.size())
- FailFullscreenTest("DidChangeView1 has different plugin size");
+ if (position.size() != screen_size_)
+ FailFullscreenTest("DidChangeView1 does not have screen size");
// Wait for the 2nd DidChangeView.
} else if (fullscreen_pending_) {
fullscreen_pending_ = false;
@@ -205,8 +209,10 @@ void TestFullscreen::DidChangeView(const pp::Rect& position,
FailFullscreenTest("DidChangeView2 is not in fullscreen");
else if (!HasMidScreen(position, screen_size_))
FailFullscreenTest("DidChangeView2 is not in the middle of the screen");
- else if (position.size() != normal_position_.size())
- FailFullscreenTest("DidChangeView2 has different plugin size");
+ else if (position.size() != screen_size_)
+ FailFullscreenTest("DidChangeView2 does not have screen size");
+ // NOTE: we cannot reliably test for clip size being equal to the screen
+ // because it might be affected by JS console, info bars, etc.
else
pp::Module::Get()->core()->CallOnMainThread(0, fullscreen_callback_);
} else if (normal_pending_) {
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
index 746b899..d13690b 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
@@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/stringprintf.h"
#include "base/utf_offset_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "ppapi/c/dev/ppb_console_dev.h"
@@ -99,6 +100,7 @@
#include "skia/ext/skia_utils_mac.h"
#endif
+using base::StringPrintf;
using ppapi::InputEventImpl;
using ppapi::StringVar;
using ppapi::thunk::EnterResourceNoLock;
@@ -115,6 +117,7 @@ using WebKit::WebConsoleMessage;
using WebKit::WebCursorInfo;
using WebKit::WebDocument;
using WebKit::WebFrame;
+using WebKit::WebElement;
using WebKit::WebInputEvent;
using WebKit::WebPluginContainer;
using WebKit::WebString;
@@ -165,6 +168,12 @@ const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_NONE;
== static_cast<int>(np_name), \
mismatching_enums)
+// <embed>/<object> attributes.
+static const char kWidth[] = "width";
+static const char kHeight[] = "height";
+static const char kBorder[] = "border"; // According to w3c, deprecated.
+static const char kStyle[] = "style";
+
COMPILE_ASSERT_MATCHING_ENUM(TypePointer, PP_CURSORTYPE_POINTER);
COMPILE_ASSERT_MATCHING_ENUM(TypeCross, PP_CURSORTYPE_CROSS);
COMPILE_ASSERT_MATCHING_ENUM(TypeHand, PP_CURSORTYPE_HAND);
@@ -237,7 +246,7 @@ bool SecurityOriginForInstance(PP_Instance instance_id,
if (!instance)
return false;
- WebKit::WebElement plugin_element = instance->container()->element();
+ WebElement plugin_element = instance->container()->element();
*security_origin = plugin_element.document().securityOrigin();
return true;
}
@@ -736,10 +745,29 @@ void PluginInstance::ViewChanged(const gfx::Rect& position,
if (sent_did_change_view_ && position == position_ && new_clip == clip_)
return;
- sent_did_change_view_ = true;
- position_ = position;
- clip_ = new_clip;
- fullscreen_ = desired_fullscreen_state_;
+ // TODO(polina): fullscreen transition might take multiple ViewChanged,
+ // so this will update the state too early. Also, when F11 is used to
+ // exit fullscreen mode, desired_fullscreen_state_ is not properly set
+ // and cannot be relied on.
+ // Pending fix: http://codereview.chromium.org/8273029/
+ // WebKit: https://bugs.webkit.org/show_bug.cgi?id=70076.
+ if (desired_fullscreen_state_ && !fullscreen_) {
+ // Entered fullscreen. Only possible via SetFullscreen.
+ fullscreen_ = true;
+ } else if (!desired_fullscreen_state_ && fullscreen_) {
+ // Exited fullscreen. Possible via SetFullscreen or F11/link.
+ fullscreen_ = false;
+ // Reset the size attributes that we hacked to fill in the screen and
+ // retrigger ViewChanged. Make sure we don't forward duplicates of
+ // this view to the plugin.
+ ResetSizeAttributesAfterFullscreen();
+ SetSentDidChangeView(position, new_clip);
+ MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&PluginInstance::ReportGeometry, this));
+ return;
+ }
+
+ SetSentDidChangeView(position, new_clip);
flash_fullscreen_ = (fullscreen_container_ != NULL);
PP_Rect pp_position, pp_clip;
@@ -1164,10 +1192,16 @@ bool PluginInstance::SetFullscreen(bool fullscreen, bool delay_report) {
VLOG(1) << "Setting fullscreen to " << (fullscreen ? "on" : "off");
desired_fullscreen_state_ = fullscreen;
- if (fullscreen)
+
+ if (fullscreen) {
+ // WebKit does not resize the plugin to fill the screen in fullscreen mode,
+ // so we will tweak plugin's attributes to support the expected behavior.
+ KeepSizeAttributesBeforeFullscreen();
+ SetSizeAttributesForFullscreen();
container_->element().requestFullScreen();
- else
+ } else {
container_->element().document().cancelFullScreen();
+ }
if (!delay_report) {
ReportGeometry();
} else {
@@ -1901,7 +1935,7 @@ PP_Var PluginInstance::ResolveRelativeToDocument(
if (!relative_string)
return PP_MakeNull();
- WebKit::WebElement plugin_element = container()->element();
+ WebElement plugin_element = container()->element();
GURL document_url = plugin_element.document().baseURL();
return ::ppapi::URLUtilImpl::GenerateURLReturn(
module()->pp_module(),
@@ -1978,5 +2012,54 @@ bool PluginInstance::CanAccessMainFrame() const {
main_document.securityOrigin());
}
+void PluginInstance::SetSentDidChangeView(const gfx::Rect& position,
+ const gfx::Rect& clip) {
+ sent_did_change_view_ = true;
+ position_ = position;
+ clip_ = clip;
+}
+
+void PluginInstance::KeepSizeAttributesBeforeFullscreen() {
+ WebElement element = container_->element();
+ width_before_fullscreen_ = element.getAttribute(WebString::fromUTF8(kWidth));
+ height_before_fullscreen_ =
+ element.getAttribute(WebString::fromUTF8(kHeight));
+ border_before_fullscreen_ =
+ element.getAttribute(WebString::fromUTF8(kBorder));
+ style_before_fullscreen_ = element.getAttribute(WebString::fromUTF8(kStyle));
+}
+
+void PluginInstance::SetSizeAttributesForFullscreen() {
+ screen_size_for_fullscreen_ = delegate()->GetScreenSize();
+ std::string width = StringPrintf("%d", screen_size_for_fullscreen_.width());
+ std::string height = StringPrintf("%d", screen_size_for_fullscreen_.height());
+
+ WebElement element = container_->element();
+ element.setAttribute(WebString::fromUTF8(kWidth), WebString::fromUTF8(width));
+ element.setAttribute(WebString::fromUTF8(kHeight),
+ WebString::fromUTF8(height));
+ element.setAttribute(WebString::fromUTF8(kBorder), WebString::fromUTF8("0"));
+
+ // There should be no style settings that matter in fullscreen mode,
+ // so just replace them instead of appending.
+ // NOTE: "position: fixed" and "display: block" reset the plugin and
+ // using %% settings might not work without them (e.g. if the plugin is a
+ // child of a container element).
+ std::string style;
+ style += StringPrintf("width: %s !important; ", width.c_str());
+ style += StringPrintf("height: %s !important; ", height.c_str());
+ style += "margin: 0 !important; padding: 0 !important; border: 0 !important";
+ container_->element().setAttribute(kStyle, WebString::fromUTF8(style));
+}
+
+void PluginInstance::ResetSizeAttributesAfterFullscreen() {
+ screen_size_for_fullscreen_ = gfx::Size();
+ WebElement element = container_->element();
+ element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_);
+ element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_);
+ element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_);
+ element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_);
+}
+
} // namespace ppapi
} // namespace webkit
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h
index 00fbfab..78c9ecd 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.h
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h
@@ -32,6 +32,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCanvas.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/gfx/rect.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
@@ -450,6 +451,15 @@ class PluginInstance : public base::RefCounted<PluginInstance>,
// compositing path.
bool IsViewAccelerated();
+ // Remember view parameters that were sent to the plugin.
+ void SetSentDidChangeView(const gfx::Rect& position, const gfx::Rect& clip);
+
+ // Track, set and reset size attributes to control the size of the plugin
+ // in and out of fullscreen mode.
+ void KeepSizeAttributesBeforeFullscreen();
+ void SetSizeAttributesForFullscreen();
+ void ResetSizeAttributesAfterFullscreen();
+
PluginDelegate* delegate_;
scoped_refptr<PluginModule> module_;
scoped_ptr< ::ppapi::PPP_Instance_Combined> instance_interface_;
@@ -570,6 +580,15 @@ class PluginInstance : public base::RefCounted<PluginInstance>,
// It reflects the previous state when in transition.
bool fullscreen_;
+ // WebKit does not resize the plugin when going into fullscreen mode, so we do
+ // this here by modifying the various plugin attributes and then restoring
+ // them on exit.
+ WebKit::WebString width_before_fullscreen_;
+ WebKit::WebString height_before_fullscreen_;
+ WebKit::WebString border_before_fullscreen_;
+ WebKit::WebString style_before_fullscreen_;
+ gfx::Size screen_size_for_fullscreen_;
+
// The MessageChannel used to implement bidirectional postMessage for the
// instance.
scoped_ptr<MessageChannel> message_channel_;