# Frames and Displays

**URL:** <https://racket.discourse.group/t/frames-and-displays/2026>\
**Category:** Questions & Answers\
**Tags:** drracket, gui\
**Created:** [June 19, 2023, 2:58pm UTC](https://racket.discourse.group/t/frames-and-displays/2026 "2023-06-19T14:58:45Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![madkins23](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/madkins23/32/1208_2.png) [@madkins23](https://racket.discourse.group/u/madkins23)\
**Post date:** [June 19, 2023, 2:58pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/1 "2023-06-19T14:58:45Z")

</div>

I have a two-display configuration running on Ubuntu Linux. My "main" screen is my laptop but the screen I usually "use" is a secondary, larger monitor that sits right in front of me. I have the launcher bar configured to be present on both displays.

I have noticed that when `DrRacket` starts up (from an icon on the launcher bar) the "loading" display shows up on the display from which I launched the application. Then, when that's done, the actual application window shows up on my laptop and I have to move it. This same behavior seems to occur with dialogs that launch from `DrRacket`, they show up on my laptop and I have to move them.

I started looking at the GUI API and there doesn't seem to be any recognition that there may be multiple displays. I'm not really expecting any, but its absence suggests that there is no recognition of or support for multiple displays.

Is there a way to cause new `frame%` and `dialog%` objects to show up on the same display as ... well I guess the application's main window?

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [June 19, 2023, 6:58pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/2 "2023-06-19T18:58:11Z")

</div>

To me it sounds like, you need to configure in your window manager such that  
the exernal screen, if present, is the primary screen.

Exact details depend on the window manager.

---

<div class="post-metadata">

**Author:** ![madkins23](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/madkins23/32/1208_2.png) [@madkins23](https://racket.discourse.group/u/madkins23)\
**Post date:** [June 19, 2023, 10:38pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/3 "2023-06-19T22:38:43Z")

</div>

Good idea. Just tried it. Doesn't make any difference. `DrRacket` always starts on the main display. Rebooted and tried again, just to make sure.

`VSCode`, `IntelliJ`, and `Goland` (the latter two are JetBrains IDEs) all seem to start on the display on which they were closed last. Tried this with the main display set each way and the behavior is the same.

There must be:

- some way that a display can be specified to the OS when opening a window,
- a way for an application to determine the display on which a window is shown, and
- a place where the applications are saving this for next time.

I suspect that the solution would be something buried deep within `racket/gui` in the `frame%` implementation. My guess would be that the window creation code specifies display `0` all of the time, or doesn't specify it and that's the default. It's almost certainly platform specific code as well.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [June 19, 2023, 11:33pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/4 "2023-06-19T23:33:53Z")

</div>

> Good idea. Just tried it. Doesn't make any difference. `DrRacket` always starts on the main display. Rebooted and tried again, just to make sure.

What do you mean by "main display" here. The laptop screen or the screen set to primary in the window manager?

Do your window manager cache old placements of windows?  
If so, you might need to flush them.

I am not using Linux, so I can't help with the concrete window manager, but  
maybe others have experience with the window manager, you are using?

There are some function for dealing with multiple displays here:

[https://docs.racket-lang.org/gui/Windowing\_Functions.html#(part.\_.Global\_.Graphics)](https://docs.racket-lang.org/gui/Windowing_Functions.html#%28part._.Global_.Graphics%29)

---

<div class="post-metadata">

**Author:** ![robby](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/robby/32/7_2.png) [@robby](https://racket.discourse.group/u/robby)\
**Post date:** [June 19, 2023, 11:35pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/5 "2023-06-19T23:35:03Z")

</div>

The short version is that racket/gui provides support to query the current monitor configuration, see:

[https://docs.racket-lang.org/gui/top-level-window\_\_\_.html#%28meth.\_%28%28%28lib.\_mred%2Fmain..rkt%29.\_top-level-window~3c~25~3e%29.\_display-changed%29%29](https://docs.racket-lang.org/gui/top-level-window___.html#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._top-level-window~3c~25~3e%29._display-changed%29%29)

And then DrRacket uses that support to try to remember where you last left a window when you had the set of monitors you have currently, and then move stuff around.

This works well for me on Mac OS so my guess is that some of the racket/gui primitives aren't working for you. Perhaps trying them out and seeing what they do and if the results make sense will lead to being able to open an issue in either the racket/gui repo (if the function return wrong results for you) or in the racket/drracket repo if drracket's handling of the results could be improved.

Hth,  
Robby

---

<div class="post-metadata">

**Author:** ![madkins23](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/madkins23/32/1208_2.png) [@madkins23](https://racket.discourse.group/u/madkins23)\
**Post date:** [June 20, 2023, 3:45am UTC](https://racket.discourse.group/t/frames-and-displays/2026/6 "2023-06-20T03:45:17Z")

</div>

It looks like `display-changed` signals a change to monitor configuration, not a change in what monitor is currently displaying a window. Fooling around with the code seems to confirm that. In addition, searching the `DrRacket` source doesn't show any use of `display-changed`.

The other functions mentioned also return monitor configuration information, not information about what monitor is currently displaying what window.

Looking in `racket-8.9/share/pkgs/gui-lib/mred/private/wx/gtk/frame.rkt` I can see the GTK calls but there's nothing like `gtk_window_set_display` or `gtk_window_display`.

I'm just not seeing any way `racket/gui` supports the connection between a `frame%` and the display (or monitor) on which it is displayed.

---

<div class="post-metadata">

**Author:** ![robby](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/robby/32/7_2.png) [@robby](https://racket.discourse.group/u/robby)\
**Post date:** [June 20, 2023, 4:32am UTC](https://racket.discourse.group/t/frames-and-displays/2026/7 "2023-06-20T04:32:33Z")

</div>

That's right: racket/gui provides the basic functionality (ie implements the connection to the underlying OS) and DrRacket uses it to try to match a particular monitor configuration to a particular window placement. I linked that one method because it links other related primitives.

Robby

---

<div class="post-metadata">

**Author:** ![madkins23](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/madkins23/32/1208_2.png) [@madkins23](https://racket.discourse.group/u/madkins23)\
**Post date:** [June 20, 2023, 12:15pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/8 "2023-06-20T12:15:21Z")

</div>

It turns out the x,y coordinates of a window are not relative to the monitor on which the window is displayed but are absolute across a virtual space encompassing both monitors (at least on Linux).

I keep the primary monitor to the left. I am able to:

- acquire a current `x,y` location from a `frame%` that I have moved to the secondary monitor that includes an `x`-value larger than the width of the primary monitor and
- create a new window on the secondary monitor by setting an `x`-value larger than the width of the primary monitor.

So it is not necessary to have the monitor number associated with a window. It should be possible to get the location on application shutdown and set it on the next invocation of that application without reference to the monitor configuration.

Now I just have to dig through the `DrRacket` codebase to find the place where it launches the main window. Any clues?

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [June 20, 2023, 4:28pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/9 "2023-06-20T16:28:36Z")

</div>

I think the primary monitor has (0,0) in the upper left corner, and the other  
monitors have coordinates relative to (0,0).

See [get-display-left-top-inset returns non-zero offset for monitor 0 on linux · Issue #223 · racket/gui · GitHub](https://github.com/racket/gui/issues/223)

I am wondering what you get when you run:

```scheme
(begin
  (require racket/gui)
  (define (get-display-info)
    (append (list (system-type 'os*) (system-type 'gc) (version) (get-display-count))
            (for/list ([monitor (in-range (get-display-count))])
              (let-values ([(x y) (get-display-size #:monitor monitor)]
                           [(dx dy) (get-display-left-top-inset #:monitor monitor)])
                (list
                 monitor
                 x y dx dy)))))
  (get-display-info))

```

A screenshot of the monitor layout might also help, if the it turns out the issues are related.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [June 20, 2023, 4:29pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/10 "2023-06-20T16:29:04Z")

</div>

> [@madkins23](#):
>
> Now I just have to dig through the `DrRacket` codebase to find the place where it launches the main window. Any clues?

> Now I just have to dig through the `DrRacket` codebase to find the place where it launches the main window. Any clues?

@robby will know.

---

<div class="post-metadata">

**Author:** ![madkins23](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/madkins23/32/1208_2.png) [@madkins23](https://racket.discourse.group/u/madkins23)\
**Post date:** [June 20, 2023, 4:49pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/11 "2023-06-20T16:49:02Z")

</div>

The crux of the biscuit is `frame:size-pref-mixin` which seems to be malfunctioning on the initial frame display. It captures the old data OK but on redisplay it seems to always re-calculate the position, ignoring the old data that was previously (and correctly) saved in the relevant preference. I'm working through it now, I can demonstrate the failure but I haven't quite figured out where it's going wrong.

---

<div class="post-metadata">

**Author:** ![madkins23](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/madkins23/32/1208_2.png) [@madkins23](https://racket.discourse.group/u/madkins23)\
**Post date:** [June 20, 2023, 5:42pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/12 "2023-06-20T17:42:39Z")

</div>

> <https://github.com/racket/gui/pull/298>
>
> I'm running Ubuntu Linux with two displays. The one on the left is a laptop whic…h I use for terminals and whatnot. Directly in front of me is a larger monitor I use for editing.
> 
> I noticed that every time I started \`DrRacket\` it would show up on the primary (left) screen. After some digging it appeared that the problem was in \`frame:size-pref-mixin\`. My test program is at the end of this description.
> 
> I believe that the issue is due to \`get-display-left-top-inset\` returning negative numbers in some cases. In this instance the left number is \`-1920\` per the following trace statement I inserted into \`get-sizes/maximzed\` when I was figuring this out:
> \`\`\`
> mon 1 delta 769 x 307 left -1920 top 0 mon size 1920 x 1080
> \`\`\`
> 
> This fails the first \`\<=\` test I that I have changed resulting in the window position always being recalculated. I changed the second one to account for vertical placement of multiple monitors.
> 
> With these changes I can turn off the secondary monitor, resulting in the window going to the primary monitor. Turning the secondary monitor back on puts the window back on the secondary monitor. I changed the display configuration to have the primary on the right and it worked there as well. I haven't done \*really\* extensive testing but the basic mechanism seems to work right except for the two items I have changed so maybe this is sufficient.
> 
> This is pretty thorny code and I don't have any Mac or Windows platforms. The two simple changes in this PR make it work for me but it may break code on other platforms.
> 
> Demo program is below (\`github\` apparently won't allow me to attach an \`.rkt\` file). Run the program then move the window to another monitor and close it. Run the program again. Not sure how to unit test this so I didn't bother.
> 
> \`\`\`
> \#lang racket
> 
> (require racket/gui framework)
> 
> (define window-title "Demo Issue")
> (define size-prefs 'demo-size-prefs)
> (define posn-prefs 'demo-posn-prefs)
> 
> (frame:setup-size-pref
> size-prefs 300 100
> #:position-preferences posn-prefs)
> 
> (define where-window%
> (class (frame:size-pref-mixin
> (frame:basic-mixin
> frame%))
> (super-new
> \[label window-title\]
> \[size-preferences-key size-prefs\]
> \[position-preferences-key posn-prefs\])
> 
> (define/override (on-size width height)
> (super on-size width height))
> 
> (define/override (on-move x y)
> (super on-move x y))))
> 
> (let (\[new-es 
> (make-eventspace)\])
> (parameterize (\[current-eventspace new-es\])
> (let (\[f (new where-window%)\])
> (send f show #t))))
> \`\`\`
> 
> I also noticed a very minor documentation error that should be self-explanatory.

---

<div class="post-metadata">

**Author:** ![robby](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/robby/32/7_2.png) [@robby](https://racket.discourse.group/u/robby)\
**Post date:** [June 21, 2023, 2:47pm UTC](https://racket.discourse.group/t/frames-and-displays/2026/13 "2023-06-21T14:47:07Z")

</div>

> [@soegaard](#):
>
> > Now I just have to dig through the `DrRacket` codebase to find the place where it launches the main window. Any clues?
> 
> @robby will know.

It looks like you found it already and I had forgotten that it was in the framework! Here's the code, just in case: [https://github.com/racket/gui/blob/master/gui-lib/framework/private/frame.rkt#L255](https://github.com/racket/gui/blob/master/gui-lib/framework/private/frame.rkt#L255)

> [@madkins23](#):
>
> The crux of the biscuit is `frame:size-pref-mixin` which seems to be malfunctioning on the initial frame display. It captures the old data OK but on redisplay it seems to always re-calculate the position, ignoring the old data that was previously (and correctly) saved in the relevant preference. I'm working through it now, I can demonstrate the failure but I haven't quite figured out where it's going wrong.

Thanks for looking into this! I have some vague memories triggered by looking at this code that sometimes dodgy things are happening and the code is trying to avoid doing bogus things. It may make sense to simply see what the current steps are happening when you see the bad behavior and report that here and maybe we can figure out how to change it.
