workaround for occasional linux window misdraw
This commit is contained in:
@@ -56,15 +56,15 @@ func main() {
|
||||
} else {
|
||||
mainWindow.Controller.DoConnectToServerWorkflow(defaultServer)
|
||||
}
|
||||
// TODO: There is a race condition with laying out the window before the
|
||||
// window creation animation on Ubuntu (and other DEs?) finishes, where
|
||||
// the window will be misdrawn into a smaller area if the animation hasn't finished.
|
||||
// This makes it much less likely to occur (not seen on dozens of startups)
|
||||
// but is a hacky "solution"!
|
||||
|
||||
// hacky workaround for https://github.com/fyne-io/fyne/issues/4964
|
||||
if runtime.GOOS == "linux" {
|
||||
time.Sleep(350 * time.Millisecond)
|
||||
mainWindow.ForceResize()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
w, h := mainWindow.DesiredSize()
|
||||
scale := mainWindow.Window.Canvas().Scale()
|
||||
SendResizeToPID(os.Getpid(), int(w*scale), int(h*scale))
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
mainWindow.Show()
|
||||
|
||||
+9
-4
@@ -89,7 +89,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
|
||||
m.BottomPanel = NewBottomPanel(app.PlaybackManager, app.ImageManager, m.Controller)
|
||||
m.container = container.NewBorder(nil, m.BottomPanel, nil, nil, m.BrowsingPane)
|
||||
m.Window.SetContent(m.container)
|
||||
m.ForceResize()
|
||||
m.setInitialSize()
|
||||
app.PlaybackManager.OnSongChange(func(item mediaprovider.MediaItem, _ *mediaprovider.Track) {
|
||||
if item == nil {
|
||||
m.Window.SetTitle(displayAppName)
|
||||
@@ -141,15 +141,20 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *MainWindow) ForceResize() {
|
||||
w := float32(m.App.Config.Application.WindowWidth)
|
||||
func (m *MainWindow) DesiredSize() (w, h float32) {
|
||||
w = float32(m.App.Config.Application.WindowWidth)
|
||||
if w <= 1 {
|
||||
w = 1000
|
||||
}
|
||||
h := float32(m.App.Config.Application.WindowHeight)
|
||||
h = float32(m.App.Config.Application.WindowHeight)
|
||||
if h <= 1 {
|
||||
h = 800
|
||||
}
|
||||
return w, h
|
||||
}
|
||||
|
||||
func (m *MainWindow) setInitialSize() {
|
||||
w, h := m.DesiredSize()
|
||||
m.Window.Resize(fyne.NewSize(w, h))
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
//go:build linux && !wayland
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xresize.h"
|
||||
|
||||
// thanks ChatGPT ;)
|
||||
int find_windows_by_pid(Display *display, Window root, pid_t pid, Window* out, int n) {
|
||||
Window *children;
|
||||
unsigned int nchildren;
|
||||
if (!XQueryTree(display, root, &root, &root, &children, &nchildren)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < nchildren; i++) {
|
||||
Atom pidAtom = XInternAtom(display, "_NET_WM_PID", True);
|
||||
if (pidAtom != None) {
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *prop_pid = NULL;
|
||||
|
||||
if (XGetWindowProperty(display, children[i], pidAtom, 0, 1, False, XA_CARDINAL,
|
||||
&type, &format, &nitems, &bytes_after, &prop_pid) == Success && prop_pid) {
|
||||
if (pid == *((pid_t *)prop_pid)) {
|
||||
out[n++] = children[i];
|
||||
}
|
||||
XFree(prop_pid);
|
||||
}
|
||||
}
|
||||
|
||||
n = find_windows_by_pid(display, children[i], pid, out, n);
|
||||
}
|
||||
|
||||
XFree(children);
|
||||
return n;
|
||||
}
|
||||
|
||||
void send_resize_event(Display *display, Window window, int width, int height) {
|
||||
XResizeWindow(display, window, width, height);
|
||||
XFlush(display);
|
||||
}
|
||||
|
||||
int send_resize_to_pid(int pid, int w, int h) {
|
||||
Display *display = XOpenDisplay(NULL);
|
||||
if (!display) {
|
||||
return 1;
|
||||
}
|
||||
int ret = 0;
|
||||
Window windows[128];
|
||||
Window root = DefaultRootWindow(display);
|
||||
|
||||
int n = find_windows_by_pid(display, root, pid, &windows, 0);
|
||||
if (n > 0) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
send_resize_event(display, windows[i], w, h);
|
||||
}
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
//go:build linux && !wayland
|
||||
|
||||
int send_resize_to_pid(int pid, int w, int h);
|
||||
@@ -0,0 +1,5 @@
|
||||
//go:build !linux || wayland
|
||||
|
||||
package main
|
||||
|
||||
func SendResizeToPID(pid, w, h int) {}
|
||||
@@ -0,0 +1,15 @@
|
||||
//go:build linux && !wayland
|
||||
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -lX11
|
||||
#include "xresize.h"
|
||||
*/
|
||||
import (
|
||||
"C"
|
||||
)
|
||||
|
||||
func SendResizeToPID(pid, w, h int) {
|
||||
C.send_resize_to_pid(C.int(pid), C.int(w), C.int(h))
|
||||
}
|
||||
Reference in New Issue
Block a user