Skip to content

Commit

Permalink
Fix popouts opening and saving as incorrect size (#622)
Browse files Browse the repository at this point in the history
* Popout widget will now open to correct size

* Api signature changes

* Changelogs

* Trigger tests

* Remove test trigger

* seperate delta height and width checks because of logic
  • Loading branch information
joehenry9498 authored Dec 12, 2023
1 parent 6319c32 commit ca4305e
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 9 deletions.
2 changes: 1 addition & 1 deletion common/api/appui-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2266,7 +2266,7 @@ export class FrontstageDef {
// (undocumented)
get rightPanel(): StagePanelDef | undefined;
// @internal (undocumented)
saveChildWindowSizeAndPosition(childWindowId: string, childWindow: Window): void;
saveChildWindowSizeAndPosition(childWindowId: string, childWindow: ChildWindow): void;
setActiveContent(): Promise<boolean>;
setActiveView(newContent: ContentControl, oldContent?: ContentControl): void;
setActiveViewFromViewport(viewport: ScreenViewport): boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/appui-react",
"comment": "Fixed bug where popouts would get incrementally smaller or larger each time opened",
"type": "none"
}
],
"packageName": "@itwin/appui-react"
}
5 changes: 5 additions & 0 deletions docs/changehistory/NextVersion.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Table of contents:
- [@itwin/appui-react](#itwinappui-react)
- [Fixes](#fixes)
- [Changes](#changes)
- [Fixes](#fixes)
- [@itwin/components-react](#itwincomponents-react)
- [Fixes](#fixes)
- [Improvements](#improvements)
Expand All @@ -21,6 +22,10 @@ Table of contents:
- Promoted `FrameworkToolAdmin` to _beta_. #618
- Correctly handle `WidgetState.Unloaded` and keep widget content unmounted when widget is unloaded. #617

### Fixes

- Fixed popout widgets getting incrementally smaller or larger each time popped out. [#563](https://github.com/iTwin/appui/issues/563)

## @itwin/components-react

### Fixes
Expand Down
20 changes: 20 additions & 0 deletions ui/appui-react/src/appui-react/childwindow/ChildWindowConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/**
* An extension of a Window to be used for Popout Widgets.
* @internal
*/
export interface ChildWindow extends Window {
/** Width that child window wants to open to */
expectedWidth?: number;
/** Height that child window wants to open to */
expectedHeight?: number;
/** Difference between width child window actually opened to as compared to expected */
deltaWidth?: number;
/** Difference between height child window actually opened to as compared to expected */
deltaHeight?: number;
/** If outer size should be used for calculations instead of inner size */
shouldUseOuterSized?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type {
OpenChildWindowInfo,
} from "../framework/FrameworkChildWindows";
import { createLayoutStore, NineZone } from "@itwin/appui-layout-react";
import type { ChildWindow } from "./ChildWindowConfig";

const childHtml = `<!DOCTYPE html>
<html>
Expand Down Expand Up @@ -141,12 +142,25 @@ export class InternalChildWindowManager implements FrameworkChildWindows {

// istanbul ignore next: Used in `open` which is not tested.
private renderChildWindowContents(
childWindow: Window,
childWindow: ChildWindow,
childWindowId: string,
content: React.ReactNode,
title: string
) {
childWindow.document.title = title;
if (childWindow.expectedHeight && childWindow.expectedWidth) {
childWindow.deltaWidth =
childWindow.expectedWidth -
(childWindow.shouldUseOuterSized
? childWindow.outerWidth
: childWindow.innerWidth);
childWindow.deltaHeight =
childWindow.expectedHeight -
(childWindow.shouldUseOuterSized
? childWindow.outerHeight
: childWindow.innerHeight);
}

const reactConnectionDiv = childWindow.document.getElementById("root");
if (reactConnectionDiv) {
// set openChildWindows now so components can use it when they mount
Expand Down Expand Up @@ -285,12 +299,19 @@ export class InternalChildWindowManager implements FrameworkChildWindows {

location = this.adjustWidowLocation(location);
const url = useDefaultPopoutUrl ? "/iTwinPopup.html" : "";
const childWindow = window.open(
const childWindow: ChildWindow | null = window.open(
url,
"",
`width=${location.width},height=${location.height},left=${location.left},top=${location.top},menubar=no,resizable=yes,scrollbars=no,status=no,location=no`
);
if (!childWindow) return false;
childWindow.expectedHeight = location.height;
childWindow.expectedWidth = location.width;

// Edge needs to use outer size
childWindow.shouldUseOuterSized =
navigator.userAgent.toLowerCase().indexOf("edg/") > -1;

if (0 === url.length) {
childWindow.document.write(childHtml);
this.renderChildWindowContents(
Expand Down
23 changes: 17 additions & 6 deletions ui/appui-react/src/appui-react/frontstage/FrontstageDef.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import type { FrontstageProvider } from "./FrontstageProvider";
import { TimeTracker } from "../configurableui/TimeTracker";
import type { ChildWindowLocationProps } from "../framework/FrameworkChildWindows";
import { PopoutWidget } from "../childwindow/PopoutWidget";
import { BentleyStatus, ProcessDetector } from "@itwin/core-bentley";
import { BentleyStatus } from "@itwin/core-bentley";
import type { FrontstageConfig } from "./FrontstageConfig";
import type { StagePanelConfig } from "../stagepanels/StagePanelConfig";
import type { WidgetConfig } from "../widgets/WidgetConfig";
Expand All @@ -57,6 +57,7 @@ import { WidgetState } from "../widgets/WidgetState";
import { InternalFrontstageManager } from "./InternalFrontstageManager";
import { InternalContentDialogManager } from "../dialog/InternalContentDialogManager";
import type { XAndY } from "@itwin/core-geometry";
import type { ChildWindow } from "../childwindow/ChildWindowConfig";

/** @internal */
export interface FrontstageEventArgs {
Expand Down Expand Up @@ -900,7 +901,7 @@ export class FrontstageDef {
/** @internal */
public saveChildWindowSizeAndPosition(
childWindowId: string,
childWindow: Window
childWindow: ChildWindow
) {
const state = this.nineZoneState;
if (!state) return;
Expand All @@ -913,11 +914,21 @@ export class FrontstageDef {
const widgetDef = this.findWidgetDef(tabId);
if (!widgetDef) return;

const adjustmentWidth = ProcessDetector.isElectronAppFrontend ? 16 : 0;
const adjustmentHeight = ProcessDetector.isElectronAppFrontend ? 39 : 0;
let width = childWindow.shouldUseOuterSized
? childWindow.outerWidth
: childWindow.innerWidth;
let height = childWindow.shouldUseOuterSized
? childWindow.outerHeight
: childWindow.innerHeight;
if (childWindow.deltaHeight) {
height = height + childWindow.deltaHeight;
if (height < 1) height = 100;
}
if (childWindow.deltaWidth) {
width = width + childWindow.deltaWidth;
if (width < 1) width = 100;
}

const width = childWindow.innerWidth + adjustmentWidth;
const height = childWindow.innerHeight + adjustmentHeight;
const bounds = Rectangle.createFromSize({ width, height }).offset({
x: childWindow.screenX,
y: childWindow.screenY,
Expand Down

0 comments on commit ca4305e

Please sign in to comment.