Skip to content

Wrong WindowInsets after navigating from multi-window to single-window #236

@azizbekian

Description

@azizbekian

Assuming it is multi-window mode, where first app is an arbitrary app and second app is Plaid, then as soon as Plaid becomes the only app in foreground (mode changes to single-window), then Plaid gets wrong WindowInsets, which results toolbar not being correctly padded.

ezgif-5-fc533d73b8

Note, had Plaid been the first app (in the top of the screen), then WindowInsets are correctly dispatched.

Thoughts to workaround

If inside onApplyWindowInsets() checked:

drawer.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
    @Override
    public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
        if (insets.getSystemWindowInsetLeft() == 0 &&
                insets.getSystemWindowInsetTop() == 0 &&
                insets.getSystemWindowInsetRight() == 0 &&
                insets.getSystemWindowInsetBottom() == 0) {
            ViewCompat.requestApplyInsets(drawer);
            return insets.consumeSystemWindowInsets();
        }
        ...
    }
});

This will solve the issue, but the side effect is, that this will result in an infinite loop in multi-window mode, because those insets are 0 in multi-window mode, which is ok. Thus, we should check whether we are in multi- or single-window mode:

if (!isInMultiWindowMode() &&
        insets.getSystemWindowInsetLeft() == 0 &&
        insets.getSystemWindowInsetTop() == 0 &&
        insets.getSystemWindowInsetRight() == 0 &&
        insets.getSystemWindowInsetBottom() == 0) {
	
	    ViewCompat.requestApplyInsets(drawer);
	    return insets.consumeSystemWindowInsets();
}

If we are in a single-window mode and insets are equal to 0, only then request for a new dispatch.

Theoretically, this should work. In practice isInMultiWindowMode() still returns true when in single-window mode. Stale value issue of isInMultiWindowMode() is described in CommonsBlog.

On my machine 250ms is the delay, that is needed for the value to reflect real multi-window state. Following piece of code would make WindowInsets correctly applied:

@Override
public WindowInsets onApplyWindowInsets(View v, final WindowInsets insets) {

    if (isInMultiWindowMode()) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (!isInMultiWindowMode() && insets.getSystemWindowInsetLeft() == 0 &&
                        insets.getSystemWindowInsetTop() == 0 &&
                        insets.getSystemWindowInsetRight() == 0 &&
                        insets.getSystemWindowInsetBottom() == 0) {
                    ViewCompat.requestApplyInsets(drawer);
                }
            }
        }, 250);
        return insets.consumeSystemWindowInsets();
    }
    ...
}

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions