From 59adc6979ab33790e3f91305b6b5f3f157a66bc8 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 23 Feb 2016 01:41:57 +0900 Subject: [PATCH] ui: Bug fix: Adjust scaling factor on Linux (#157) --- internal/ui/scaling.go | 23 +++++++++++++++++ internal/ui/scaling_linux.go | 49 ++++++++++++++++++++++++++++++++++++ internal/ui/ui_glfw.go | 12 ++++----- 3 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 internal/ui/scaling.go create mode 100644 internal/ui/scaling_linux.go diff --git a/internal/ui/scaling.go b/internal/ui/scaling.go new file mode 100644 index 000000000..bc90db8d9 --- /dev/null +++ b/internal/ui/scaling.go @@ -0,0 +1,23 @@ +// Copyright 2016 Hajime Hoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !linux + +package ui + +func adjustScaleForGLFW(scale int) int { + // On Windows and OSX, GLFW already considers High-DPI scaling + // and scale doesn't have to be adjusted. + return scale +} diff --git a/internal/ui/scaling_linux.go b/internal/ui/scaling_linux.go new file mode 100644 index 000000000..6db8199b7 --- /dev/null +++ b/internal/ui/scaling_linux.go @@ -0,0 +1,49 @@ +// Copyright 2016 Hajime Hoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ui + +import ( + "fmt" + "os/exec" + "regexp" + "strconv" +) + +var scalingFactorSyntax = regexp.MustCompile(`\Auint32\s+(\d+)\s*\z`) +var deviceScaleFactor = 0 + +// adjustScaleForGLFW adjusts the given scale which is passed to the GLFW API. +func adjustScaleForGLFW(scale int) int { + if 0 < deviceScaleFactor { + return scale * deviceScaleFactor + } + // Execute gsettings command instead of calling gtk functions so as not to depend on + // gobject-2.0 library. + c := exec.Command("gsettings", "get", "org.gnome.desktop.interface", "scaling-factor") + o, err := c.Output() + if err != nil { + panic(fmt.Sprintf("graphics: executing gsettings error %v", err)) + } + m := scalingFactorSyntax.FindStringSubmatch(string(o)) + if m == nil { + panic("graphics: gsettings result syntax is not expected") + } + s, err := strconv.Atoi(m[1]) + if err != nil { + panic(fmt.Sprintf("graphics: %v", err)) + } + deviceScaleFactor = s + return scale * deviceScaleFactor +} diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index d029de338..663edf998 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -108,13 +108,13 @@ type userInterface struct { } func (u *userInterface) start(width, height, scale int, title string) (actualScale int, err error) { - videoMode := glfw.GetPrimaryMonitor().GetVideoMode() - x := (videoMode.Width - width*scale) / 2 - y := (videoMode.Height - height*scale) / 3 - u.setScreenSize(width, height, scale) u.window.SetTitle(title) u.window.Show() + + videoMode := glfw.GetPrimaryMonitor().GetVideoMode() + x := (videoMode.Width - width*adjustScaleForGLFW(scale)) / 2 + y := (videoMode.Height - height*adjustScaleForGLFW(scale)) / 3 u.window.SetPos(x, y) return u.actualScale, nil @@ -158,7 +158,7 @@ func (u *userInterface) setScreenSize(width, height, scale int) bool { } // To make sure the current existing framebuffers are rendered, - // swap buffers here. + // swap buffers here before SetSize is called. u.context.BindZeroFramebuffer() u.swapBuffers() @@ -168,7 +168,7 @@ func (u *userInterface) setScreenSize(width, height, scale int) bool { window.SetFramebufferSizeCallback(nil) close(ch) }) - window.SetSize(width*scale, height*scale) + window.SetSize(width*adjustScaleForGLFW(scale), height*adjustScaleForGLFW(scale)) event: for {