workaround for occasional linux window misdraw
This commit is contained in:
@@ -56,15 +56,15 @@ func main() {
|
|||||||
} else {
|
} else {
|
||||||
mainWindow.Controller.DoConnectToServerWorkflow(defaultServer)
|
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
|
// hacky workaround for https://github.com/fyne-io/fyne/issues/4964
|
||||||
// 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"!
|
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
time.Sleep(350 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
mainWindow.ForceResize()
|
w, h := mainWindow.DesiredSize()
|
||||||
|
scale := mainWindow.Window.Canvas().Scale()
|
||||||
|
SendResizeToPID(os.Getpid(), int(w*scale), int(h*scale))
|
||||||
}
|
}
|
||||||
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
mainWindow.Show()
|
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.BottomPanel = NewBottomPanel(app.PlaybackManager, app.ImageManager, m.Controller)
|
||||||
m.container = container.NewBorder(nil, m.BottomPanel, nil, nil, m.BrowsingPane)
|
m.container = container.NewBorder(nil, m.BottomPanel, nil, nil, m.BrowsingPane)
|
||||||
m.Window.SetContent(m.container)
|
m.Window.SetContent(m.container)
|
||||||
m.ForceResize()
|
m.setInitialSize()
|
||||||
app.PlaybackManager.OnSongChange(func(item mediaprovider.MediaItem, _ *mediaprovider.Track) {
|
app.PlaybackManager.OnSongChange(func(item mediaprovider.MediaItem, _ *mediaprovider.Track) {
|
||||||
if item == nil {
|
if item == nil {
|
||||||
m.Window.SetTitle(displayAppName)
|
m.Window.SetTitle(displayAppName)
|
||||||
@@ -141,15 +141,20 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
|
|||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MainWindow) ForceResize() {
|
func (m *MainWindow) DesiredSize() (w, h float32) {
|
||||||
w := float32(m.App.Config.Application.WindowWidth)
|
w = float32(m.App.Config.Application.WindowWidth)
|
||||||
if w <= 1 {
|
if w <= 1 {
|
||||||
w = 1000
|
w = 1000
|
||||||
}
|
}
|
||||||
h := float32(m.App.Config.Application.WindowHeight)
|
h = float32(m.App.Config.Application.WindowHeight)
|
||||||
if h <= 1 {
|
if h <= 1 {
|
||||||
h = 800
|
h = 800
|
||||||
}
|
}
|
||||||
|
return w, h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MainWindow) setInitialSize() {
|
||||||
|
w, h := m.DesiredSize()
|
||||||
m.Window.Resize(fyne.NewSize(w, h))
|
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