author | Jim Mathies <jmathies@mozilla.com> |
Wed, 12 Nov 2014 14:59:19 -0600 | |
changeset 239674 | dcc233b91a99e7d8cfaa39b508d2eb2c2496fab6 |
parent 239673 | 10f4a7ba42c82935d3c5082bc9d5af9129b38ab6 |
child 239675 | bcaebd09531ca0c862f92d5e2ff80ffb22741419 |
push id | 4311 |
push user | raliiev@mozilla.com |
push date | Mon, 12 Jan 2015 19:37:41 +0000 |
treeherder | mozilla-beta@150c9fed433b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 669200 |
milestone | 36.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2592,17 +2592,17 @@ nsLayoutUtils::TransformFrameRectToAnces NSFloatPixelsToAppUnits(float(result.y), destAppUnitsPerDevPixel), NSFloatPixelsToAppUnits(float(result.width), destAppUnitsPerDevPixel), NSFloatPixelsToAppUnits(float(result.height), destAppUnitsPerDevPixel)); } static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) { nsIntPoint offset(0, 0); while ((aWidget->WindowType() == eWindowType_child || - aWidget->WindowType() == eWindowType_plugin)) { + aWidget->IsPlugin())) { nsIWidget* parent = aWidget->GetParent(); if (!parent) { break; } nsIntRect bounds; aWidget->GetBounds(bounds); offset += bounds.TopLeft(); aWidget = parent;
--- a/view/nsViewManager.cpp +++ b/view/nsViewManager.cpp @@ -548,17 +548,17 @@ nsViewManager::InvalidateWidgetArea(nsVi if (widget->GetTransparencyMode() != eTransparencyTransparent) { for (nsIWidget* childWidget = widget->GetFirstChild(); childWidget; childWidget = childWidget->GetNextSibling()) { nsView* view = nsView::GetViewFor(childWidget); NS_ASSERTION(view != aWidgetView, "will recur infinitely"); nsWindowType type = childWidget->WindowType(); if (view && childWidget->IsVisible() && type != eWindowType_popup) { - NS_ASSERTION(type == eWindowType_plugin, + NS_ASSERTION(childWidget->IsPlugin(), "Only plugin or popup widgets can be children!"); // We do not need to invalidate in plugin widgets, but we should // exclude them from the invalidation region IF we're not on // Mac. On Mac we need to draw under plugin widgets, because // plugin widgets are basically invisible #ifndef XP_MACOSX // GetBounds should compensate for chrome on a toplevel widget
--- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -212,16 +212,39 @@ PuppetWidget::Resize(double aWidth, if (!oldBounds.IsEqualEdges(mBounds) && mAttachedWidgetListener) { mAttachedWidgetListener->WindowResized(this, mBounds.width, mBounds.height); } return NS_OK; } +nsresult +PuppetWidget::ConfigureChildren(const nsTArray<Configuration>& aConfigurations) +{ + for (uint32_t i = 0; i < aConfigurations.Length(); ++i) { + const Configuration& configuration = aConfigurations[i]; + PuppetWidget* w = static_cast<PuppetWidget*>(configuration.mChild); + NS_ASSERTION(w->GetParent() == this, + "Configured widget is not a child"); + w->SetWindowClipRegion(configuration.mClipRegion, true); + nsIntRect bounds; + w->GetBounds(bounds); + if (bounds.Size() != configuration.mBounds.Size()) { + w->Resize(configuration.mBounds.x, configuration.mBounds.y, + configuration.mBounds.width, configuration.mBounds.height, + true); + } else if (bounds.TopLeft() != configuration.mBounds.TopLeft()) { + w->Move(configuration.mBounds.x, configuration.mBounds.y); + } + w->SetWindowClipRegion(configuration.mClipRegion, false); + } + return NS_OK; +} + NS_IMETHODIMP PuppetWidget::SetFocus(bool aRaise) { // XXX/cjones: someone who knows about event handling needs to // decide how this should work. return NS_OK; }
--- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -32,18 +32,18 @@ namespace mozilla { namespace dom { class TabChild; } namespace widget { struct AutoCacheNativeKeyCommands; -class PuppetWidget MOZ_FINAL : public nsBaseWidget, - public nsSupportsWeakReference +class PuppetWidget : public nsBaseWidget, + public nsSupportsWeakReference { typedef mozilla::dom::TabChild TabChild; typedef mozilla::gfx::DrawTarget DrawTarget; typedef nsBaseWidget Base; // The width and height of the "widget" are clamped to this. static const size_t kMaxDimension; @@ -101,19 +101,17 @@ public: // widget is supposed to entail NS_IMETHOD Enable(bool aState) { mEnabled = aState; return NS_OK; } virtual bool IsEnabled() const { return mEnabled; } NS_IMETHOD SetFocus(bool aRaise = false); - // PuppetWidgets don't care about children. - virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) - { return NS_OK; } + virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations); NS_IMETHOD Invalidate(const nsIntRect& aRect); // This API is going away, steer clear. virtual void Scroll(const nsIntPoint& aDelta, const nsTArray<nsIntRect>& aDestRects, const nsTArray<Configuration>& aReconfigureChildren) { /* dead man walking */ } @@ -190,16 +188,20 @@ public: virtual TabChild* GetOwningTabChild() MOZ_OVERRIDE { return mTabChild; } virtual void ClearBackingScaleCache() { mDPI = -1; mDefaultScale = -1; } +protected: + bool mEnabled; + bool mVisible; + private: nsresult Paint(); void SetChild(PuppetWidget* aChild); nsresult IMEEndComposition(bool aCancel); nsresult NotifyIMEOfFocusChange(bool aFocus); nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification); @@ -223,18 +225,16 @@ private: // it's possible for TabChild to outlive the PuppetWidget, we clear // this weak reference in Destroy() TabChild* mTabChild; // The "widget" to which we delegate events if we don't have an // event handler. nsRefPtr<PuppetWidget> mChild; nsIntRegion mDirtyRegion; nsRevocableEventPtr<PaintTask> mPaintTask; - bool mEnabled; - bool mVisible; // XXX/cjones: keeping this around until we teach LayerManager to do // retained-content-only transactions mozilla::RefPtr<DrawTarget> mDrawTarget; // IME nsIMEUpdatePreference mIMEPreferenceOfParent; bool mIMEComposing; // Latest seqno received through events uint32_t mIMELastReceivedSeqno;
--- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3621,16 +3621,18 @@ nsWindow::Create(nsIWidget *aPare gdk_window_input_shape_combine_region(mGdkWindow, region, 0, 0); cairo_region_destroy(region); #endif } } } break; case eWindowType_plugin: + case eWindowType_plugin_ipc_chrome: + case eWindowType_plugin_ipc_content: case eWindowType_child: { if (parentMozContainer) { mGdkWindow = CreateGdkWindow(parentGdkWindow, parentMozContainer); mHasMappedToplevel = parentnsWindow->mHasMappedToplevel; } else if (parentGtkContainer) { // This MozContainer has its own window for drawing and receives // events because there is no mShell widget (corresponding to this @@ -4080,16 +4082,23 @@ nsWindow::GetTransparencyMode() } return mIsTransparent ? eTransparencyTransparent : eTransparencyOpaque; } nsresult nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations) { + // If this is a remotely updated widget we receive clipping, position, and + // size information from a source other than our owner. Don't let our parent + // update this information. + if (mWindowType == eWindowType_plugin_ipc_chrome) { + return NS_OK; + } + for (uint32_t i = 0; i < aConfigurations.Length(); ++i) { const Configuration& configuration = aConfigurations[i]; nsWindow* w = static_cast<nsWindow*>(configuration.mChild); NS_ASSERTION(w->GetParent() == this, "Configured widget is not a child"); w->SetWindowClipRegion(configuration.mClipRegion, true); if (w->mBounds.Size() != configuration.mBounds.Size()) { w->Resize(configuration.mBounds.x, configuration.mBounds.y, @@ -4147,17 +4156,17 @@ GetIntRects(pixman_region32& aRegion, ns int nRects; pixman_box32* boxes = pixman_region32_rectangles(&aRegion, &nRects); aRects->SetCapacity(aRects->Length() + nRects); for (int i = 0; i < nRects; ++i) { aRects->AppendElement(ToIntRect(boxes[i])); } } -void +nsresult nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, bool aIntersectWithExisting) { const nsTArray<nsIntRect>* newRects = &aRects; nsAutoTArray<nsIntRect,1> intersectRects; if (aIntersectWithExisting) { nsAutoTArray<nsIntRect,1> existingRects; @@ -4171,30 +4180,30 @@ nsWindow::SetWindowClipRegion(const nsTA pixman_region32_init(&intersectRegion); pixman_region32_intersect(&intersectRegion, &newRegion, &existingRegion); // If mClipRects is null we haven't set a clip rect yet, so we // need to set the clip even if it is equal. if (mClipRects && pixman_region32_equal(&intersectRegion, &existingRegion)) { - return; + return NS_OK; } if (!pixman_region32_equal(&intersectRegion, &newRegion)) { GetIntRects(intersectRegion, &intersectRects); newRects = &intersectRects; } } if (!StoreWindowClipRegion(*newRects)) - return; + return NS_OK; if (!mGdkWindow) - return; + return NS_OK; #if (MOZ_WIDGET_GTK == 2) GdkRegion *region = gdk_region_new(); // aborts on OOM for (uint32_t i = 0; i < newRects->Length(); ++i) { const nsIntRect& r = newRects->ElementAt(i); GdkRectangle rect = { r.x, r.y, r.width, r.height }; gdk_region_union_with_rect(region, &rect); } @@ -4207,18 +4216,18 @@ nsWindow::SetWindowClipRegion(const nsTA const nsIntRect& r = newRects->ElementAt(i); cairo_rectangle_int_t rect = { r.x, r.y, r.width, r.height }; cairo_region_union_rectangle(region, &rect); } gdk_window_shape_combine_region(mGdkWindow, region, 0, 0); cairo_region_destroy(region); #endif - - return; + + return NS_OK; } void nsWindow::ResizeTransparencyBitmap() { if (!mTransparencyBitmap) return;
--- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -137,17 +137,18 @@ public: NS_IMETHOD SetIcon(const nsAString& aIconSpec); NS_IMETHOD SetWindowClass(const nsAString& xulWinType); virtual nsIntPoint WidgetToScreenOffset(); NS_IMETHOD EnableDragDrop(bool aEnable); NS_IMETHOD CaptureMouse(bool aCapture); NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, bool aDoCapture); NS_IMETHOD GetAttention(int32_t aCycleCount); - + virtual nsresult SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, + bool aIntersectWithExisting) MOZ_OVERRIDE; virtual bool HasPendingInputEvent(); NS_IMETHOD MakeFullScreen(bool aFullScreen); NS_IMETHOD HideWindowChrome(bool aShouldHide); /** * GetLastUserInputTime returns a timestamp for the most recent user input * event. This is intended for pointer grab requests (including drags). @@ -335,18 +336,16 @@ private: nsWindow *GetContainerWindow(); void SetUrgencyHint(GtkWidget *top_window, bool state); void *SetupPluginPort(void); void SetDefaultIcon(void); void InitButtonEvent(mozilla::WidgetMouseEvent& aEvent, GdkEventButton* aGdkEvent); bool DispatchCommandEvent(nsIAtom* aCommand); bool DispatchContentCommandEvent(int32_t aMsg); - void SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, - bool aIntersectWithExisting); bool CheckForRollup(gdouble aMouseX, gdouble aMouseY, bool aIsWheel, bool aAlwaysRollup); bool GetDragInfo(mozilla::WidgetMouseEvent* aMouseEvent, GdkWindow** aWindow, gint* aButton, gint* aRootX, gint* aRootY); void ClearCachedResources(); GtkWidget *mShell;
--- a/widget/moz.build +++ b/widget/moz.build @@ -92,24 +92,27 @@ if CONFIG['MOZ_METRO']: XPIDL_MODULE = 'widget' EXPORTS += [ 'ContentHelper.h', 'GfxDriverInfo.h', 'GfxInfoBase.h', 'GfxInfoCollector.h', 'InputData.h', + 'nsBaseScreen.h', + 'nsBaseWidget.h', 'nsIDeviceContextSpec.h', 'nsIPluginWidget.h', 'nsIRollupListener.h', 'nsIWidget.h', 'nsIWidgetListener.h', 'nsPrintOptionsImpl.h', 'nsWidgetInitData.h', 'nsWidgetsCID.h', + 'PuppetWidget.h', ] EXPORTS.mozilla += [ 'BasicEvents.h', 'CommandList.h', 'ContentEvents.h', 'EventClassList.h', 'EventForwards.h',
--- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -657,16 +657,69 @@ nsBaseWidget::GetWindowClipRegion(nsTArr { if (mClipRects) { aRects->AppendElements(mClipRects.get(), mClipRectCount); } else { aRects->AppendElement(nsIntRect(0, 0, mBounds.width, mBounds.height)); } } +const nsIntRegion +nsBaseWidget::RegionFromArray(const nsTArray<nsIntRect>& aRects) +{ + nsIntRegion region; + for (uint32_t i = 0; i < aRects.Length(); ++i) { + region.Or(region, aRects[i]); + } + return region; +} + +void +nsBaseWidget::ArrayFromRegion(const nsIntRegion& aRegion, nsTArray<nsIntRect>& aRects) +{ + const nsIntRect* r; + for (nsIntRegionRectIterator iter(aRegion); (r = iter.Next());) { + aRects.AppendElement(*r); + } +} + +nsresult +nsBaseWidget::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, + bool aIntersectWithExisting) +{ + if (!aIntersectWithExisting) { + nsBaseWidget::StoreWindowClipRegion(aRects); + } else { + // In this case still early return if nothing changed. + if (mClipRects && mClipRectCount == aRects.Length() && + memcmp(mClipRects, + aRects.Elements(), + sizeof(nsIntRect)*mClipRectCount) == 0) { + return NS_OK; + } + + // get current rects + nsTArray<nsIntRect> currentRects; + GetWindowClipRegion(¤tRects); + // create region from them + nsIntRegion currentRegion = RegionFromArray(currentRects); + // create region from new rects + nsIntRegion newRegion = RegionFromArray(aRects); + // intersect regions + nsIntRegion intersection; + intersection.And(currentRegion, newRegion); + // create int rect array from intersection + nsTArray<nsIntRect> rects; + ArrayFromRegion(intersection, rects); + // store + nsBaseWidget::StoreWindowClipRegion(rects); + } + return NS_OK; +} + //------------------------------------------------------------------------- // // Set window shadow style // //------------------------------------------------------------------------- NS_IMETHODIMP nsBaseWidget::SetWindowShadowStyle(int32_t aMode) {
--- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -145,16 +145,17 @@ public: virtual void DrawWindowOverlay(LayerManagerComposite* aManager, nsIntRect aRect) {} virtual mozilla::TemporaryRef<mozilla::gfx::DrawTarget> StartRemoteDrawing(); virtual void EndRemoteDrawing() { }; virtual void CleanupRemoteDrawing() { }; virtual void UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries) {} NS_IMETHOD SetModal(bool aModal); virtual uint32_t GetMaxTouchPoints() const; NS_IMETHOD SetWindowClass(const nsAString& xulWinType); + virtual nsresult SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, bool aIntersectWithExisting); // Return whether this widget interprets parameters to Move and Resize APIs // as "global display pixels" rather than "device pixels", and therefore // applies its GetDefaultScale() value to them before using them as mBounds // etc (which are always stored in device pixels). // Note that APIs that -get- the widget's position/size/bounds, rather than // -setting- them (i.e. moving or resizing the widget) will always return // values in the widget's device pixels. bool BoundsUseDisplayPixels() const { @@ -294,16 +295,19 @@ protected: const nsAString &aIconSuffix, nsIFile **aResult); virtual void OnDestroy(); virtual void BaseCreate(nsIWidget *aParent, const nsIntRect &aRect, nsDeviceContext *aContext, nsWidgetInitData *aInitData); + const nsIntRegion RegionFromArray(const nsTArray<nsIntRect>& aRects); + void ArrayFromRegion(const nsIntRegion& aRegion, nsTArray<nsIntRect>& aRects); + virtual nsIContent* GetLastRollup() { return mLastRollup; } virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, int32_t aNativeKeyCode, uint32_t aModifierFlags,
--- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -93,18 +93,18 @@ typedef void* nsNativeWidget; #ifdef XP_WIN #define NS_NATIVE_TSF_THREAD_MGR 100 #define NS_NATIVE_TSF_CATEGORY_MGR 101 #define NS_NATIVE_TSF_DISPLAY_ATTR_MGR 102 #define NS_NATIVE_ICOREWINDOW 103 // winrt specific #endif #define NS_IWIDGET_IID \ -{ 0xcfe7543b, 0x8c0e, 0x40c3, \ - { 0x9a, 0x6d, 0x77, 0x6e, 0x84, 0x8a, 0x7c, 0xfc } }; +{ 0x13239ca, 0xaf3f, 0x4f27, \ + { 0xaf, 0x83, 0x47, 0xa9, 0x82, 0x3d, 0x99, 0xee } }; /* * Window shadow styles * Also used for the -moz-window-shadow CSS property */ #define NS_STYLE_WINDOW_SHADOW_NONE 0 #define NS_STYLE_WINDOW_SHADOW_DEFAULT 1 @@ -1269,16 +1269,25 @@ class nsIWidget : public nsISupports { uint32_t aHotspotX, uint32_t aHotspotY) = 0; /** * Get the window type of this widget. */ nsWindowType WindowType() { return mWindowType; } /** + * Determines if this widget is one of the three types of plugin widgets. + */ + bool IsPlugin() { + return mWindowType == eWindowType_plugin || + mWindowType == eWindowType_plugin_ipc_chrome || + mWindowType == eWindowType_plugin_ipc_content; + } + + /** * Set the transparency mode of the top-level window containing this widget. * So, e.g., if you call this on the widget for an IFRAME, the top level * browser window containing the IFRAME actually gets set. Be careful. * * This can fail if the platform doesn't support * transparency/glass. By default widgets are not * transparent. This will also fail if the toplevel window is not * a Mozilla window, e.g., if the widget is in an embedded @@ -1320,16 +1329,18 @@ class nsIWidget : public nsISupports { * This will invalidate areas of the children that have changed, but * does not need to invalidate any part of this widget. * * Children should be moved in the order given; the array is * sorted so to minimize unnecessary invalidation if children are * moved in that order. */ virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) = 0; + virtual nsresult SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, + bool aIntersectWithExisting) = 0; /** * Appends to aRects the rectangles constituting this widget's clip * region. If this widget is not clipped, appends a single rectangle * (0, 0, bounds.width, bounds.height). */ virtual void GetWindowClipRegion(nsTArray<nsIntRect>* aRects) = 0;
--- a/widget/nsWidgetInitData.h +++ b/widget/nsWidgetInitData.h @@ -8,25 +8,27 @@ /** * Window types * * Don't alter previously encoded enum values - 3rd party apps may look at * these. */ enum nsWindowType { - eWindowType_toplevel, // default top level window - eWindowType_dialog, // top level window but usually handled differently - // by the OS - eWindowType_popup, // used for combo boxes, etc - eWindowType_child, // child windows (contained inside a window on the - // desktop (has no border)) - eWindowType_invisible, // windows that are invisible or offscreen - eWindowType_plugin, // plugin window - eWindowType_sheet // MacOSX sheet (special dialog class) + eWindowType_toplevel, // default top level window + eWindowType_dialog, // top level window but usually handled differently + // by the OS + eWindowType_popup, // used for combo boxes, etc + eWindowType_child, // child windows (contained inside a window on the + // desktop (has no border)) + eWindowType_invisible, // windows that are invisible or offscreen + eWindowType_plugin, // plugin window + eWindowType_plugin_ipc_chrome, // chrome side native widget for plugins (e10s) + eWindowType_plugin_ipc_content, // content side puppet widget for plugins (e10s) + eWindowType_sheet, // MacOSX sheet (special dialog class) }; /** * Popup types * * For eWindowType_popup */ enum nsPopupType {
--- a/widget/windows/WinMouseScrollHandler.cpp +++ b/widget/windows/WinMouseScrollHandler.cpp @@ -457,17 +457,17 @@ MouseScrollHandler::ProcessNativeMouseWh MOZ_ASSERT(destWindow, "destWindow must not be NULL"); // If the found window is our plugin window, it means that the message // has been handled by the plugin but not consumed. We should handle the // message on its parent window. However, note that the DOM event may // cause accessing the plugin. Therefore, we should unlock the plugin // process by using PostMessage(). - if (destWindow->WindowType() == eWindowType_plugin) { + if (destWindow->IsPlugin()) { destWindow = destWindow->GetParentWindowBase(false); if (!destWindow) { PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, ("MouseScroll::ProcessNativeMouseWheelMessage: " "Our window which is a parent of a plugin window is not found")); return; } } @@ -496,17 +496,17 @@ MouseScrollHandler::ProcessNativeMouseWh return; } // If we're a plugin window (MozillaWindowClass) and cursor in this window, // the message shouldn't go to plugin's wndproc again. So, we should handle // it on parent window. However, note that the DOM event may cause accessing // the plugin. Therefore, we should unlock the plugin process by using // PostMessage(). - if (aWidget->WindowType() == eWindowType_plugin && + if (aWidget->IsPlugin() && aWidget->GetWindowHandle() == pluginWnd) { nsWindowBase* destWindow = aWidget->GetParentWindowBase(false); if (!destWindow) { PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, ("MouseScroll::ProcessNativeMouseWheelMessage: Our normal window which " "is a parent of this plugin window is not found")); return; } @@ -1527,17 +1527,17 @@ MouseScrollHandler::SynthesizingEvent::N if (mStatus == SENDING_MESSAGE && mMessage == aMessage && mWParam == aWParam && mLParam == aLParam) { mStatus = NATIVE_MESSAGE_RECEIVED; if (aWidget && aWidget->GetWindowHandle() == mWnd) { return; } // If the target window is not ours and received window is our plugin // window, it comes from child window of the plugin. - if (aWidget && aWidget->WindowType() == eWindowType_plugin && + if (aWidget && aWidget->IsPlugin() && !WinUtils::GetNSWindowBasePtr(mWnd)) { return; } // Otherwise, the message may not be sent by us. } PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS, ("MouseScrollHandler::SynthesizingEvent::NativeMessageReceived(): "
--- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -543,17 +543,19 @@ nsWindow::Create(nsIWidget *aParent, if (aInitData->mDropShadow) { GetWindowPopupClass(className); } else { GetWindowClass(className); } // Plugins are created in the disabled state so that they can't // steal focus away from our main window. This is especially // important if the plugin has loaded in a background tab. - if(aInitData->mWindowType == eWindowType_plugin) { + if (aInitData->mWindowType == eWindowType_plugin || + aInitData->mWindowType == eWindowType_plugin_ipc_chrome || + aInitData->mWindowType == eWindowType_plugin_ipc_content) { style |= WS_DISABLED; } mWnd = ::CreateWindowExW(extendedStyle, className.get(), L"", style, aRect.x, aRect.y, @@ -569,17 +571,17 @@ nsWindow::Create(nsIWidget *aParent, return NS_ERROR_FAILURE; } if (mIsRTL && WinUtils::dwmSetWindowAttributePtr) { DWORD dwAttribute = TRUE; WinUtils::dwmSetWindowAttributePtr(mWnd, DWMWA_NONCLIENT_RTL_LAYOUT, &dwAttribute, sizeof dwAttribute); } - if (mWindowType != eWindowType_plugin && + if (!IsPlugin() && mWindowType != eWindowType_invisible && MouseScrollHandler::Device::IsFakeScrollableWindowNeeded()) { // Ugly Thinkpad Driver Hack (Bugs 507222 and 594977) // // We create two zero-sized windows as descendants of the top-level window, // like so: // // Top-level window (MozillaWindowClass) @@ -789,16 +791,18 @@ void nsWindow::GetWindowPopupClass(nsStr // Return nsWindow styles DWORD nsWindow::WindowStyle() { DWORD style; switch (mWindowType) { case eWindowType_plugin: + case eWindowType_plugin_ipc_chrome: + case eWindowType_plugin_ipc_content: case eWindowType_child: style = WS_OVERLAPPED; break; case eWindowType_dialog: style = WS_OVERLAPPED | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_3DLOOK | DS_MODALFRAME | WS_CLIPCHILDREN; if (mBorderStyle != eBorderStyle_default) @@ -868,16 +872,18 @@ DWORD nsWindow::WindowStyle() } // Return nsWindow extended styles DWORD nsWindow::WindowExStyle() { switch (mWindowType) { case eWindowType_plugin: + case eWindowType_plugin_ipc_chrome: + case eWindowType_plugin_ipc_content: case eWindowType_child: return 0; case eWindowType_dialog: return WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME; case eWindowType_popup: { @@ -1412,17 +1418,17 @@ NS_METHOD nsWindow::Move(double aX, doub } #endif ClearThemeRegion(); UINT flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE; // Workaround SetWindowPos bug with D3D9. If our window has a clip // region, some drivers or OSes may incorrectly copy into the clipped-out // area. - if (mWindowType == eWindowType_plugin && + if (IsPlugin() && (!mLayerManager || mLayerManager->GetBackendType() == LayersBackend::LAYERS_D3D9) && mClipRects && (mClipRectCount != 1 || !mClipRects[0].IsEqualInterior(nsIntRect(0, 0, mBounds.width, mBounds.height)))) { flags |= SWP_NOCOPYBITS; } VERIFY(::SetWindowPos(mWnd, nullptr, x, y, 0, 0, flags)); SetThemeRegion(); @@ -2636,39 +2642,29 @@ nsTransparencyMode nsWindow::GetTranspar return GetTopLevelWindow(true)->GetWindowTranslucencyInner(); } void nsWindow::SetTransparencyMode(nsTransparencyMode aMode) { GetTopLevelWindow(true)->SetWindowTranslucencyInner(aMode); } -static const nsIntRegion -RegionFromArray(const nsTArray<nsIntRect>& aRects) -{ - nsIntRegion region; - for (uint32_t i = 0; i < aRects.Length(); ++i) { - region.Or(region, aRects[i]); - } - return region; -} - void nsWindow::UpdateOpaqueRegion(const nsIntRegion &aOpaqueRegion) { if (!HasGlass() || GetParent()) return; // If there is no opaque region or hidechrome=true, set margins // to support a full sheet of glass. Comments in MSDN indicate // all values must be set to -1 to get a full sheet of glass. MARGINS margins = { -1, -1, -1, -1 }; if (!aOpaqueRegion.IsEmpty()) { nsIntRect pluginBounds; for (nsIWidget* child = GetFirstChild(); child; child = child->GetNextSibling()) { - if (child->WindowType() == eWindowType_plugin) { + if (child->IsPlugin()) { // Collect the bounds of all plugins for GetLargestRectangle. nsIntRect childBounds; child->GetBounds(childBounds); pluginBounds.UnionRect(pluginBounds, childBounds); } } nsIntRect clientBounds; @@ -5323,17 +5319,17 @@ nsWindow::ProcessMessage(UINT msg, WPARA case WM_GESTURE: result = OnGesture(wParam, lParam); break; case WM_GESTURENOTIFY: { if (mWindowType != eWindowType_invisible && - mWindowType != eWindowType_plugin) { + !IsPlugin()) { // A GestureNotify event is dispatched to decide which single-finger panning // direction should be active (including none) and if pan feedback should // be displayed. Java and plugin windows can make their own calls. if (gIsPointerEventsEnabled) { result = false; break; } @@ -6416,16 +6412,23 @@ static void InvalidatePluginAsWorkaround ::InvalidateRect(next, &rect, FALSE); } } nsresult nsWindow::ConfigureChildren(const nsTArray<Configuration>& aConfigurations) { + // If this is a remotely updated widget we receive clipping, position, and + // size information from a source other than our owner. Don't let our parent + // update this information. + if (mWindowType == eWindowType_plugin_ipc_chrome) { + return NS_OK; + } + // XXXroc we could use BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos // here, if that helps in some situations. So far I haven't seen a // need. for (uint32_t i = 0; i < aConfigurations.Length(); ++i) { const Configuration& configuration = aConfigurations[i]; nsWindow* w = static_cast<nsWindow*>(configuration.mChild); NS_ASSERTION(w->GetParent() == this, "Configured widget is not a child"); @@ -6478,58 +6481,21 @@ CreateHRGNFromArray(const nsTArray<nsInt const nsIntRect& r = aRects[i]; bounds.UnionRect(bounds, r); ::SetRect(&rects[i], r.x, r.y, r.XMost(), r.YMost()); } ::SetRect(&data->rdh.rcBound, bounds.x, bounds.y, bounds.XMost(), bounds.YMost()); return ::ExtCreateRegion(nullptr, buf.Length(), data); } -static void -ArrayFromRegion(const nsIntRegion& aRegion, nsTArray<nsIntRect>& aRects) -{ - const nsIntRect* r; - for (nsIntRegionRectIterator iter(aRegion); (r = iter.Next());) { - aRects.AppendElement(*r); - } -} - nsresult nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, bool aIntersectWithExisting) { - if (!aIntersectWithExisting) { - if (!StoreWindowClipRegion(aRects)) - return NS_OK; - } else { - // In this case still early return if nothing changed. - if (mClipRects && mClipRectCount == aRects.Length() && - memcmp(mClipRects, - aRects.Elements(), - sizeof(nsIntRect)*mClipRectCount) == 0) { - return NS_OK; - } - - // get current rects - nsTArray<nsIntRect> currentRects; - GetWindowClipRegion(¤tRects); - // create region from them - nsIntRegion currentRegion = RegionFromArray(currentRects); - // create region from new rects - nsIntRegion newRegion = RegionFromArray(aRects); - // intersect regions - nsIntRegion intersection; - intersection.And(currentRegion, newRegion); - // create int rect array from intersection - nsTArray<nsIntRect> rects; - ArrayFromRegion(intersection, rects); - // store - if (!StoreWindowClipRegion(rects)) - return NS_OK; - } + nsBaseWidget::SetWindowClipRegion(aRects, aIntersectWithExisting); HRGN dest = CreateHRGNFromArray(aRects); if (!dest) return NS_ERROR_OUT_OF_MEMORY; if (aIntersectWithExisting) { HRGN current = ::CreateRectRgn(0, 0, 0, 0); if (current) { @@ -6539,18 +6505,18 @@ nsWindow::SetWindowClipRegion(const nsTA ::DeleteObject(current); } } // If a plugin is not visible, especially if it is in a background tab, // it should not be able to steal keyboard focus. This code checks whether // the region that the plugin is being clipped to is NULLREGION. If it is, // the plugin window gets disabled. - if(mWindowType == eWindowType_plugin) { - if(NULLREGION == ::CombineRgn(dest, dest, dest, RGN_OR)) { + if (IsPlugin()) { + if (NULLREGION == ::CombineRgn(dest, dest, dest, RGN_OR)) { ::ShowWindow(mWnd, SW_HIDE); ::EnableWindow(mWnd, FALSE); } else { ::EnableWindow(mWnd, TRUE); ::ShowWindow(mWnd, SW_SHOW); } } if (!::SetWindowRgn(mWnd, dest, TRUE)) { @@ -7141,17 +7107,17 @@ LRESULT CALLBACK nsWindow::MozSpecialMou case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: { MOUSEHOOKSTRUCT* ms = (MOUSEHOOKSTRUCT*)lParam; nsIWidget* mozWin = WinUtils::GetNSWindowPtr(ms->hwnd); if (mozWin) { // If this window is windowed plugin window, the mouse events are not // sent to us. - if (static_cast<nsWindow*>(mozWin)->mWindowType == eWindowType_plugin) + if (static_cast<nsWindow*>(mozWin)->IsPlugin()) ScheduleHookTimer(ms->hwnd, (UINT)wParam); } else { ScheduleHookTimer(ms->hwnd, (UINT)wParam); } break; } } }
--- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -441,18 +441,18 @@ protected: static bool IsAsyncResponseEvent(UINT aMsg, LRESULT& aResult); void IPCWindowProcHandler(UINT& msg, WPARAM& wParam, LPARAM& lParam); /** * Misc. */ void StopFlashing(); static bool IsTopLevelMouseExit(HWND aWnd); - nsresult SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, - bool aIntersectWithExisting); + virtual nsresult SetWindowClipRegion(const nsTArray<nsIntRect>& aRects, + bool aIntersectWithExisting) MOZ_OVERRIDE; nsIntRegion GetRegionToPaint(bool aForceFullRepaint, PAINTSTRUCT ps, HDC aDC); static void ActivateOtherWindowHelper(HWND aWnd); void ClearCachedResources(); nsIWidgetListener* GetPaintListener(); static bool IsRenderMode(gfxWindowsPlatform::RenderMode aMode); protected:
--- a/widget/windows/nsWindowGfx.cpp +++ b/widget/windows/nsWindowGfx.cpp @@ -179,18 +179,17 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t { // We never have reentrant paint events, except when we're running our RPC // windows event spin loop. If we don't trap for this, we'll try to paint, // but view manager will refuse to paint the surface, resulting is black // flashes on the plugin rendering surface. if (mozilla::ipc::MessageChannel::IsSpinLoopActive() && mPainting) return false; - if (mWindowType == eWindowType_plugin) { - + if (IsPlugin()) { /** * After we CallUpdateWindow to the child, occasionally a WM_PAINT message * is posted to the parent event loop with an empty update rect. Do a * dummy paint so that Windows stops dispatching WM_PAINT in an inifinite * loop. See bug 543788. */ RECT updateRect; if (!GetUpdateRect(mWnd, &updateRect, FALSE) ||