Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get the current window's screen info #1513

Open
halostatue opened this issue Dec 4, 2024 · 5 comments
Open

Get the current window's screen info #1513

halostatue opened this issue Dec 4, 2024 · 5 comments
Labels
Feature Request New features request. Not an existing issue or bug.
Milestone

Comments

@halostatue
Copy link

Is your feature request about something that is currently impossible or hard to do? Please describe the problem.

Background: I have multiple machines and two screens on one of them. On my main machine, on the secondary screen where I usually run MacVim, I have my font to :h16, but I need it at :h12 (or so) on my main laptop screen (or on my secondary machine where there is no secondary screen).

Describe the solution you'd like

I would like to be able to have a function in MacVim return the current window's screen information—screen width / height in pixels, screen name, other details; similar to the output of system_profiler SPDisplaysDataType:

Graphics/Displays:

    Apple M4 Pro:

      Chipset Model: Apple M4 Pro
      Type: GPU
      Bus: Built-In
      Total Number of Cores: 16
      Vendor: Apple (0x106b)
      Metal Support: Metal 3
      Displays:
        Color LCD:
          Display Type: Built-in Liquid Retina XDR Display
          Resolution: 3024 x 1964 Retina
          Main Display: Yes
          Mirror: Off
          Online: Yes
          Automatically Adjust Brightness: Yes
          Connection Type: Internal

If possible, it would be nice to have an event (WindowScreenChanged or something like that) which could be used to trigger when the window has been moved to a different screen or the screen has been resized or something.

Describe alternatives you've considered

I don't think that there are alternatives which let me know which screen the current window is on, even if some of this could be executed via osascript.

@ychin ychin added this to the Backlog milestone Jan 10, 2025
@ychin ychin added the Feature Request New features request. Not an existing issue or bug. label Jan 10, 2025
@ychin
Copy link
Member

ychin commented Jan 10, 2025

Huh, that's an interesting thought. I wonder if this should be a cross-platform Vim GUI API. It does seem like it needs both an autocmd and a function to query it. Let me think about it a little. I do see the value of this.

@chdiza
Copy link
Contributor

chdiza commented Jan 12, 2025

There is (or at least used to be) a neat little CLI app called screenresolution (check Homebrew) that returns the screen res and other info. I used to use it all the time in a plugin for moving the MacVim window around. You might check to see if it can return the current screen.

@halostatue
Copy link
Author

Unfortunately, it doesn't know anything about the "active" screen. (The first run was on my secondary screen; the second run was on my primary screen.)

│ screenresolution get
2025-01-12 19:50:32.924 screenresolution[30408:3876872] starting screenresolution argv=screenresolution get
2025-01-12 19:50:32.962 screenresolution[30408:3876872] Display 0: 1512x982x32@120
2025-01-12 19:50:32.962 screenresolution[30408:3876872] Display 1: 1080x1920x32@60

│ ~
│ screenresolution get
2025-01-12 19:50:43.536 screenresolution[30441:3877233] starting screenresolution argv=screenresolution get
2025-01-12 19:50:43.572 screenresolution[30441:3877233] Display 0: 1512x982x32@120
2025-01-12 19:50:43.573 screenresolution[30441:3877233] Display 1: 1080x1920x32@60

@ychin
Copy link
Member

ychin commented Jan 13, 2025

I think the bigger issue is mostly that you would want a way to query the MacVim window to see which screen it is in. It's ideal for this to be exposed by MacVim itself.

@ychin
Copy link
Member

ychin commented Jan 13, 2025

I was thinking more about it, you can actually already query the info you want. In macOS, the window position is global across all screens. The main screen usually starts at (0,0), and say if you have a screen to its left it could start at something like (-1920, -98). You can use getwinpos() within Vim to query the window position of the current GUI window and see which screen it is in.

FWIW you don't really need a third-party program (e.g. screenresolution) to query screen resolution for this purpose. Just for illustrative purpose, you can write the following Swift program which I call "screeninfo" (either run it directly in a screeninfo.swift, or ideally compile it using swiftc to get a more optimized version):

#! /usr/bin/swift
import Cocoa
var findPoint: NSPoint?
if CommandLine.arguments.count > 1 {
    findPoint = NSPointFromString(CommandLine.arguments[1])
}
var output = [[String:Any]]()
for (index, screen) in NSScreen.screens.enumerated() {
    if let p = findPoint {
        if (!screen.frame.contains(p)) {
            continue;
        }
    }
    output.append(["frame": try JSONSerialization.jsonObject(with: JSONEncoder().encode(screen.frame)),
                   "main": NSScreen.main == screen,
                   "refreshRate": screen.maximumFramesPerSecond,
                   "scaleFactor": screen.backingScaleFactor,
                   "index": index,
                   "name": screen.localizedName])
}
let jsonData = try JSONSerialization.data(withJSONObject: output)
print(String(data: jsonData, encoding: String.Encoding.utf8)!)

If you call it directly it will print out a JSON info of your screens. If you pass it a point as a command-line argument (e.g. (23,45) it will only output the screen that contains this specific point.

If I run it locally I see something like this:

➜ ychin ~/Dev/testbed/swift% ./screeninfo
[
{"name":"Built-in Retina Display","index":0,"scaleFactor":2,"frame":[[0,0],[1512,982]],"refreshRate":120,"main":true},
{"name":"LG HDR 4K","index":1,"scaleFactor":2,"frame":[[-1920,-98],[1920,1080]],"refreshRate":60,"main":false}
]

Within Vim, you can call :echo json_decode(system('screeninfo ' .. '"' .. string(getwinpos()) .. '"')) (with my MacVim window on my second monitor) and it will be something like this that you can then parse in Vimscript (the "frame" of a screen is (origin, size)):

[{'refreshRate': 60, 'index': 1, 'name': 'LG HDR 4K', 'scaleFactor': 2, 'main': v:false, 'frame': [[-1920, -98], [1920, 1080]]'}]

I guess one issue is we don't have an autocmd that could detect a GUI window has moved or changed screen, so you won't have a way to automatically detect that this has happened.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request New features request. Not an existing issue or bug.
Projects
None yet
Development

No branches or pull requests

3 participants