Closed Bug 478519 Opened 15 years ago Closed 15 years ago

suppress painting when windows are not visible (obscured or minimized)

Categories

(Core :: Widget: Gtk, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: karlt, Assigned: karlt)

References

()

Details

Attachments

(1 file, 1 obsolete file)

There is confusion in (gtk2) nsWindow::IsVisible over whether it really
returns whether the nsWindow is visible or merely that Show(TRUE) has been
called.

The following callers of nsIWidget::IsVisible are interpreting the return
value as IsShown:

  nsViewManager::AddCoveringWidgetsToOpaqueRegion
  nsWindowWatcher::OpenWindowJSInternal
  nsContainerFrame::SyncFrameViewProperties

And the windows implementation of nsIWidget::IsVisible returns a value
consistent with IsShown.

The callers within (gtk2) nsWindow seem to have been designed around
VisibilityNotify events and thus seem interested in whether the window is
visible to the user.

The original (gtk2) nsWindow::IsVisible implementation was based only on
VisibilityNotify events.  The implementation was changed for bug 241187, when
it was discovered that VisibiltyNotify events don't get sent when the window
becomes unmapped, and again in bug 281551, when it was discovered that callers
wanted IsShown.
Attached patch patch (obsolete) — Splinter Review
This suppresses passing invalidation regions to gdk when the drawing area is not visible to the user.

A new IsVisible method is added for use within nsWindow to indicate whether any part of the window is visible to the user.  It is unfortunate to have two methods with the same name but different meaning, but I can't think of a name better than IsVisible for the new method.  Really it seems that the nsIWidget method has the wrong name but I'd prefer not to change that interface.

I've tested this with kwin-3.5.9.  Painting is suppressed when windows are minimized or on inactive desktops.  Without kompmgr running, painting is also suppressed when windows are fully obscured by other windows.  (Apparently the window remains unobscured when mapped and the window manager is compositing, even when the window is behind an opaque window.)
Blocks: 451341
No longer blocks: 451341
Depends on: 451341
Blocks: 493331
No longer blocks: 493331
I've been using the patch for a few months, and haven't noticed any problems, and I have noticed that performance is better for invalidation-intensive things on other desktops.
Attached patch patch v1.1Splinter Review
updated to trunk and changed the name of the new IsVisible method to CanBeSeen
Attachment #362355 - Attachment is obsolete: true
Attachment #390560 - Flags: review?(roc)
+    if (!mIsShown || !mIsVisible)
+        return PR_FALSE;
...
+    mIsVisible =
+        topWidget &&
+        !(gdk_window_get_state(topWidget->window) &
+          (GDK_WINDOW_STATE_ICONIFIED|GDK_WINDOW_STATE_WITHDRAWN));

If mIsVisible gets set to false due to the toplevel window being iconified/withdrawn, how does it ever get set to true again?
(In reply to comment #5)
> If mIsVisible gets set to false due to the toplevel window being
> iconified/withdrawn, how does it ever get set to true again?

It gets set to true in OnVisibilityNotifyEvent() in response to
VisibilityNotify events.

VisibilityNotify events do not get sent when window changes state from
viewable to not viewable (it or an ancestor is unmapped - the X11 concept of
viewable [and mapped] differs from GDK's concept when windows are iconified).

But VisibilityNotify events do get sent when the window changes state from not
viewable to viewable.  This is documented here:

http://tronche.com/gui/x/xlib/events/window-state-change/visibility.html

  * When the window changes state from ... not viewable to viewable and
    completely unobscured, the X server generates the event with the state
    member of the XVisibilityEvent structure set to VisibilityUnobscured.

  * When the window changes state from ... not viewable to viewable and
    partially obscured, the X server generates the event with the state member
    of the XVisibilityEvent structure set to VisibilityPartiallyObscured.

  * When the window changes state from ... not viewable to viewable and
    fully obscured, the X server generates the event with the state member of
    the XVisibilityEvent structure set to VisibilityFullyObscured.
Comment on attachment 390560 [details] [diff] [review]
patch v1.1

Please add a comment explaining that.
Attachment #390560 - Flags: review?(roc) → review+
http://hg.mozilla.org/mozilla-central/rev/4626eaf57d84
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: