api-issue-tracker
api-issue-tracker copied to clipboard
`UI::scale_factor` does not return correct value - always returns scaling for primary display
SketchUp Ruby API Issue
UI::scale_factor does not return correct value - always returns scaling for primary display
VERSION: 2022
This method does not return correct value when SketchUp runs on external display. It always returns the display scaling of the primary display. So for example, if the primary display is scaled to 125% (as recommended) but SketchUp is running on an external secondary display scaled at 100%, this method returns 1.25.
The issue is seen on Windows, but there are also other issues on the Mac platform.
Should this method have an optional argument to get the scaling factor for a specific display in the system's display set ? (Ie, where no argument is 0, being the primary display.)
Should the Sketchup or UI module have a getter method to return the display number that SketchUp is running on ?
scale = UI::scale_factor(display: Sketchup.display_number)
And then, if the UI::HtmlDialog class also got a #display_number instance method, we could do:
scale = UI::scale_factor(display: @dialog.display_number)
The number should be set when it is shown. But have a default of 0 after instancing before shown.
RELATED ISSUES:
I encountered this issue when using an external monitor on my Mac, and this is the temporary workaround I am using to resolve it:
def self.verify_ui_scale
dialog = UI::HtmlDialog.new(dialog_title: "ui_scale", width: 300, height: 300)
html = <<-EOT
<!DOCTYPE html>
<html><script> window.onload = function() { sketchup.ready(window.outerWidth, window.devicePixelRatio) }; </script></html>
EOT
dialog.add_action_callback("ready") do |_a, _width, pixel_ratio|
self.scale_factor = pixel_ratio
dialog.close
Sketchup.focus if Sketchup.respond_to?(:focus)
end
dialog.set_html(html)
dialog.center
dialog.show
end
I wonder if there is a better solution?
Does the dialog.center call ensure that the dialog window is opened upon the correct display monitor ?
Logged as: SKEXT-3654
I encountered this issue when using an external monitor on my Mac, and this is the temporary workaround I am using to resolve it: ...
This "workaround" does not work on Windows platform. The pixel ratio returned on a 100% scaled display still returns 1.25.
I just tested the Sketchup::View#text_bounds method which states that it uses UI.scale_factor to scale the text drawn by View#draw_text.
Weirdly, the text is scaled correctly on the external 150% display even though UI.scale_factor returns 1.25 for the internal "Main" 125% display.
So, my conclusion is that it should then be possible to fix the UI.scale_factor method if the Sketchup::View#text_bounds method can get it right.
@voqhai I wonder if there is a better solution?
As to a workaround, .. perhaps the following ...
It might also show a bug ... that it always scales to the external display regardless of which display SketchUp is on.
def display_scaling
position = Geom::Point3d.new(200, 200, 0)
view = Sketchup.active_model.active_view
want = 20.0
high = view.text_bounds(position, 'Hello SketchUp', font: 'Arial', size: want).height
high / want
end
I have experimented with Sketchup::View#text_bounds, but it seems to be ineffective on macOS. I have found an alternative approach that works pretty effectively (not tested on Windows yet).
def self.true_ui_scale(view = Sketchup.active_model.active_view)
cam = view.camera
center = cam.target
origin_size = 100
d = view.pixels_to_model(origin_size, center)
point = center.offset(cam.up, d)
line3d = [center, point]
line2d = line3d.map { |pt| view.screen_coords(pt) }
screen_size = line2d[0].distance(line2d[1])
(screen_size / origin_size).round(1)
end