Position a modal dialog window (or center it on screen)?

Is there any way to for a modal dialog popup window to the center of the screen or give it position coordinates?

I’m thinking that it can’t be done… but just wanted to ask hoping that I may be wrong???

Right now, it is always putting the dialog near the lower left corner of the screen. It will remember if the user moves the window until Photoshop is restarted. Then it will go back to the same location near the lower left corner. Ideally, I’d like the modal dialogs to just pop up in the center of the screen.

Hi.

At first I got the same behaviour, the dialog was always at the lower left corner of the screen.
But when I started to put content inside, after maybe 300px of width and height then it displayed in center…
Also if you try this UXP sample script (I tried it on inDesign) the modal should be centered :

    const { app } = require("indesign");
    const dialog = app.dialogs.add();
    const col = dialog.dialogColumns.add();
    const colText = col.staticTexts.add();
    colText.staticLabel = 'Hello !';
    dialog.show();
    dialog.destroy();

Assuming we’re talking about dialogs created as HTMLElements and shown with something like showModal() or uxpShowModal(), could you share some code because for me the behaviour is as @ddbell outlined – default position bottom left, then wherever the user moves the dialog to until app relaunch.

The code you have shared, using app.dialogs.add(), is interesting. It is using InDesign’s Dialog class (I don’t know whether Photoshop has an equivalent). Those dialogs behave as native modal dialogs behave – always appear in the centre of the screen and can’t be moved. The downside is that (unless you know different) you can’t build them with html/javascript so you’re constrained by the widgets available. As an example, I’d like to have a modal dialog which offers the user a choice whether to continue or not, showing two buttons ‘Yes’ and ‘No’. That can be done with HTMLElement dialogs but not, as far as I know, with InDesign’s Dialog class.

I have built all my dialogs as HTMLElements but am considering rebuilding at least some of them using InDesign’s Dialog class simply because the weird positioning is so annoying – InDesign is put into a modal state and the user has to look all around the screen to find the dialog that needs to be dismissed.

All InDesign’s native modal dialogs appear centred in the screen and can’t be moved. Why can’t Adobe give us uxp dialogs that behave like that?

Philip

Hi Philip.

In Design 2024, the code I shared with you gives this centered modal :


As you can see it has 2 buttons (Ok and Cancel) but as far as I know we can’t change labels.
We only can hide the Cancel one by using : dialog.canCancel = false;
Nothing else I guess : https://developer.adobe.com/indesign/dom/api/d/Dialog/

There is another code with HTML construction :

async function main() {
    const {app} = require('indesign');

    const modal = document.createElement('dialog');
    const div = document.createElement('div');
    div.style.width="300px";
    div.style.height="300px"; // use 350px and the modal will be centered...
    div.appendChild(document.createTextNode('Hello from HTML modal'));
    modal.appendChild(div);
    document.body.appendChild(modal);
    await modal.showModal();

    return new Promise(() => {});
}

await main();

The strange here : if the modal is 300px or less of height, it will pop in to lower left corner of the screen. But if you set its height to 350px or more, then it will be centered…
I don’t have this behaviour with the “native dialog”

I tried to put sp-heading, sp-body in the modal but I got the same issue : if the modal is too small it won’t be centered…

Hope It can help…

@Tristan Oooh, that’s fascinating!

I can’t immediately see where the difference is between your ‘HTML construction’ code and mine, but I must have something in my code that is causing my dialogs to appear bottom left by default (whatever their size).

I really didn’t think it was possible to have centred as the default position, but now I’m motivated to figure it out.

Thanks very much

Philip

Just to answer the original question . . .

It can be (always) centred.

Here is a screen recording showing a dialog being repeatedly opened, moved and closed. The significant thing is that whenever it is opened it is centred in the screen.

Like @ddbell my dialogs had been (weirdly) defaulting to a position bottom left of the screen. I had assumed it was just one of those uxp bugs until @Tristan gave us code (above) that reliably centres a modal dialog.

I have done some further testing and found a number of things in the code that can cause the dialog to default to a bottom left position:

(1) It might be obvious, but the dialog (before being shown) must be in the document body (not nested anywhere else).

In the code for my test plugin, I have this in my index.html file:

<body>
	<uxp-panel panelid="dialogsPanel">
		<sp-action-button-group>
			<sp-action-button size="s">Open Centred Modal</sp-action-button>
		</sp-action-button-group>
	</uxp-panel>
	<dialog data-id="centred-modal-dialog">
		<sp-button variant="cta">Close Me</sp-button>
	</dialog>
</body>

The dialog is in the body tag and outside the uxp-panel tag. (If you’re programmatically creating the dialog, you need to append the dialog to the document body as in @Tristan’s code: document.body.appendChild(modal);)

(2) and (3) There seem to be two things that need to be set in passing options to the showModal function. This is what I have in my code:

const centredModalDialog = document.querySelector('dialog[data-id="centred-modal-dialog"]');
centredModalDialog.id = window.crypto.randomUUID();
centredModalDialog.showModal(
	{
		resize: "both", // required (cannot be "none")
		size: {
			width: 258,
			height: 258 // required (must be 258 or greater)
		}
	}
)
.then((response) => {
	console.log(response);
})
.catch((error) => {
	console.log(error);
});

Again, @Tristan had discovered that having a small number in the height causes the dialog to appear bottom left. The magic number is 258! Lower than 258, the dialog appears bottom left; 258 or higher, the dialog appears centred.

Edit Nov 22 – Based on a little further experimentation, it seems there may not be just one single magic number. InDesign especially seems to need a higher number on different computers. I’m guessing there is some calculation going on, perhaps based on screen size or chosen display settings.

The other requirement is that the resize property has to be set to “both” – it can’t be set to “none”. (You can give the dialog minSize and maxSize values identical to the size values if you don’t want any resizing.)

The final piece of the jigsaw is causing Photoshop or InDesign (this works the same in both applications) to centre the dialog each time it is opened (irrespective of whether or not the user has previously moved the dialog).

The solution to this I owe to @pedro who discovered that changing the id of the dialog before it is opened triggers the application into treating the dialog as a new dialog to be positioned in its default position (i.e. centred):
https://forums.creativeclouddeveloper.com/t/indesign-modals-are-not-dimensioned-as-expected/7424

So, in my html file I have given my dialog a data-id attribute (so that I can reference it with document.querySelector()) but not an id attribute. Then, in my javascript code (above) before showing the dialog I assign it a random id:
centredModalDialog.id = window.crypto.randomUUID();.

Philip

3 Likes