зеркало из https://github.com/mozilla/gecko-dev.git
Bug 669200 - Various widget changes to support two new types of plugin widget. r=roc
This commit is contained in:
Родитель
b66f6f1244
Коммит
a323270a8b
|
@ -2597,7 +2597,7 @@ nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
|
|||
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;
|
||||
|
|
|
@ -553,7 +553,7 @@ nsViewManager::InvalidateWidgetArea(nsView *aWidgetView,
|
|||
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
|
||||
|
|
|
@ -217,6 +217,29 @@ PuppetWidget::Resize(double aWidth,
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -37,8 +37,8 @@ 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;
|
||||
|
@ -106,9 +106,7 @@ public:
|
|||
|
||||
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);
|
||||
|
||||
|
@ -195,6 +193,10 @@ public:
|
|||
mDefaultScale = -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mEnabled;
|
||||
bool mVisible;
|
||||
|
||||
private:
|
||||
nsresult Paint();
|
||||
|
||||
|
@ -228,8 +230,6 @@ private:
|
|||
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;
|
||||
|
|
|
@ -3626,6 +3626,8 @@ nsWindow::Create(nsIWidget *aParent,
|
|||
}
|
||||
break;
|
||||
case eWindowType_plugin:
|
||||
case eWindowType_plugin_ipc_chrome:
|
||||
case eWindowType_plugin_ipc_content:
|
||||
case eWindowType_child: {
|
||||
if (parentMozContainer) {
|
||||
mGdkWindow = CreateGdkWindow(parentGdkWindow, parentMozContainer);
|
||||
|
@ -4085,6 +4087,13 @@ nsWindow::GetTransparencyMode()
|
|||
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);
|
||||
|
@ -4152,7 +4161,7 @@ GetIntRects(pixman_region32& aRegion, nsTArray<nsIntRect>* aRects)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
|
||||
bool aIntersectWithExisting)
|
||||
{
|
||||
|
@ -4176,7 +4185,7 @@ nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
|
|||
// 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)) {
|
||||
|
@ -4186,10 +4195,10 @@ nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -4212,8 +4221,8 @@ nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
|
|||
gdk_window_shape_combine_region(mGdkWindow, region, 0, 0);
|
||||
cairo_region_destroy(region);
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -142,7 +142,8 @@ public:
|
|||
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);
|
||||
|
@ -340,8 +341,6 @@ private:
|
|||
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,
|
||||
|
|
|
@ -97,6 +97,8 @@ EXPORTS += [
|
|||
'GfxInfoBase.h',
|
||||
'GfxInfoCollector.h',
|
||||
'InputData.h',
|
||||
'nsBaseScreen.h',
|
||||
'nsBaseWidget.h',
|
||||
'nsIDeviceContextSpec.h',
|
||||
'nsIPluginWidget.h',
|
||||
'nsIRollupListener.h',
|
||||
|
@ -105,6 +107,7 @@ EXPORTS += [
|
|||
'nsPrintOptionsImpl.h',
|
||||
'nsWidgetInitData.h',
|
||||
'nsWidgetsCID.h',
|
||||
'PuppetWidget.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
|
|
|
@ -662,6 +662,59 @@ nsBaseWidget::GetWindowClipRegion(nsTArray<nsIntRect>* aRects)
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -150,6 +150,7 @@ public:
|
|||
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
|
||||
|
@ -299,6 +300,9 @@ protected:
|
|||
nsDeviceContext *aContext,
|
||||
nsWidgetInitData *aInitData);
|
||||
|
||||
const nsIntRegion RegionFromArray(const nsTArray<nsIntRect>& aRects);
|
||||
void ArrayFromRegion(const nsIntRegion& aRegion, nsTArray<nsIntRect>& aRects);
|
||||
|
||||
virtual nsIContent* GetLastRollup()
|
||||
{
|
||||
return mLastRollup;
|
||||
|
|
|
@ -98,8 +98,8 @@ typedef void* nsNativeWidget;
|
|||
#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
|
||||
|
@ -1273,6 +1273,15 @@ class nsIWidget : public nsISupports {
|
|||
*/
|
||||
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
|
||||
|
@ -1325,6 +1334,8 @@ class nsIWidget : public nsISupports {
|
|||
* 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
|
||||
|
|
|
@ -13,15 +13,17 @@
|
|||
* 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)
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -462,7 +462,7 @@ MouseScrollHandler::ProcessNativeMouseWheelMessage(nsWindowBase* aWidget,
|
|||
// 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,
|
||||
|
@ -501,7 +501,7 @@ MouseScrollHandler::ProcessNativeMouseWheelMessage(nsWindowBase* aWidget,
|
|||
// 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) {
|
||||
|
@ -1532,7 +1532,7 @@ MouseScrollHandler::SynthesizingEvent::NativeMessageReceived(nsWindowBase* aWidg
|
|||
}
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -548,7 +548,9 @@ nsWindow::Create(nsIWidget *aParent,
|
|||
// 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,
|
||||
|
@ -574,7 +576,7 @@ nsWindow::Create(nsIWidget *aParent,
|
|||
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)
|
||||
|
@ -794,6 +796,8 @@ DWORD nsWindow::WindowStyle()
|
|||
|
||||
switch (mWindowType) {
|
||||
case eWindowType_plugin:
|
||||
case eWindowType_plugin_ipc_chrome:
|
||||
case eWindowType_plugin_ipc_content:
|
||||
case eWindowType_child:
|
||||
style = WS_OVERLAPPED;
|
||||
break;
|
||||
|
@ -873,6 +877,8 @@ DWORD nsWindow::WindowExStyle()
|
|||
switch (mWindowType)
|
||||
{
|
||||
case eWindowType_plugin:
|
||||
case eWindowType_plugin_ipc_chrome:
|
||||
case eWindowType_plugin_ipc_content:
|
||||
case eWindowType_child:
|
||||
return 0;
|
||||
|
||||
|
@ -1417,7 +1423,7 @@ NS_METHOD nsWindow::Move(double aX, double aY)
|
|||
// 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)))) {
|
||||
|
@ -2641,16 +2647,6 @@ 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())
|
||||
|
@ -2663,7 +2659,7 @@ void nsWindow::UpdateOpaqueRegion(const nsIntRegion &aOpaqueRegion)
|
|||
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);
|
||||
|
@ -5328,7 +5324,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
|||
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.
|
||||
|
@ -6421,6 +6417,13 @@ static void InvalidatePluginAsWorkaround(nsWindow *aWindow, const nsIntRect &aRe
|
|||
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.
|
||||
|
@ -6483,48 +6486,11 @@ CreateHRGNFromArray(const nsTArray<nsIntRect>& aRects)
|
|||
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)
|
||||
|
@ -6544,8 +6510,8 @@ nsWindow::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
|
|||
// 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 {
|
||||
|
@ -7146,7 +7112,7 @@ LRESULT CALLBACK nsWindow::MozSpecialMouseProc(int code, WPARAM wParam, LPARAM l
|
|||
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);
|
||||
|
|
|
@ -446,8 +446,8 @@ protected:
|
|||
*/
|
||||
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);
|
||||
|
|
|
@ -184,8 +184,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel)
|
|||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче