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

After maximize window does not restore to normal size #373

Open
damanis opened this issue Jun 18, 2022 · 14 comments
Open

After maximize window does not restore to normal size #373

damanis opened this issue Jun 18, 2022 · 14 comments

Comments

@damanis
Copy link

damanis commented Jun 18, 2022

How to reproduce

  • Open goneovim window, for example 100 columns x 50 lines
  • Maximize window horizontally, vertically or full
  • Unmaximize window
    Expected behavior: window restore to previous size, 100 cols x 50 lines
    Actual behavior: window size is same as in maximized state.
@akiyosi
Copy link
Owner

akiyosi commented Jun 19, 2022

@damanis
Hi, Thanks for the issue report.

What specific means are you using for each Window operation in the reproduction procedure you provided?
I understand that some window operations use the interface provided by Goneovim (e.g. GonvimMaximize), while others are platform-specific (e.g. Win key + directional key in Windows, Window Manager in Linux).

@damanis
Copy link
Author

damanis commented Jun 19, 2022

@akiyosi
I configure shortcuts in window manager (WindowMaker).
But same effect with wmctrl: wmctrl -i -r <win_id> -b "add,maximized_horz"

@damanis
Copy link
Author

damanis commented Sep 10, 2022

After GonvimMaximize a window restores properly.
In both cases, changing window state by GonvimMaxmize and by window manager, xprop returns same window property
_NET_WM_STATE(ATOM) = _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT
But in GonvimMaxmize Qt WindowState() returns 2, while after change by window manager WindowState() returns 0.

@damanis
Copy link
Author

damanis commented Sep 10, 2022

The function func (e *Editor) resizeMainWindow() is called before window state is changed, so e.window.WindowState() == core.Qt__WindowMaximized is false and geometry updated.
Seems, QResizeEvent does not provide enough data and need to use ConnectChangeEvent() to handle maximize/unmaximize by window manager.

@akiyosi
Copy link
Owner

akiyosi commented Sep 10, 2022

@damanis
As you point out, ConnectResizeEvent does not have sufficient information to address this issue. Also, since the WindowStateChange event is also fired asynchronously, it is possible that the event notification may not have been received yet at the time resizeMainWindow() is executed.

I' ll try to create a test binary that handles the state based on WindowStateChange as a trial.

By the way, am I correct in my understanding that you have WindowGeometryBasedOnFontmetrics enabled?

@damanis
Copy link
Author

damanis commented Sep 10, 2022

@akiyosi
In my tests ConnectResizeEvent is coming before WindowStateChange event.
WindowGeometryBasedOnFontmetrics is enabled to define window size by set lines and columns.

@akiyosi
Copy link
Owner

akiyosi commented Sep 12, 2022

@damanis
I have tested on my machine and as you have confirmed, WindowStateChange seems to be emitted after ResizeEvent. This means that it is difficult to simply determine if a given ResizeEvent is accompanied by a WindowStateChange event when it is emitted.
One solution, for example, it is possible to ignore ResizeEvent emitted after a GonvimMaximized command is executed until a WindowStateChange event is emitted. However, this solution will not work for events emitted outside of the Goneovim application, such as those controlled by wmctrl or similar.

Do you have any ideas?

@damanis
Copy link
Author

damanis commented Sep 12, 2022

@akiyosi
Now I use GonvimMaximized to maximize and wmctrl to unmaximize.
I will try some options, but usually I can debug on week-end (Fri-Sat) only.

@damanis
Copy link
Author

damanis commented Sep 13, 2022

@akiyosi

Do you have any ideas?

I have one idea, but it may be platform depended.
The resize callback instead of check window.state() can check main window flags _NET_WM_STATE_* set by window manager (e.g., via wmctrl). These flags from FreeDesktop standard, so should be some API. So, in Linux it should work. I think, something like this should be in Windows and MAC, but I have no details.
It's possible, Qt provides an API, so this will work on all platforms.
I think, need to protect only maximise state. If I don't mistake, full screen is not part of standard.

@damanis
Copy link
Author

damanis commented Sep 17, 2022

@akiyosi
I tried add timer after WindowGeometryBasedOnFontmetrics checking and put rest code to goroutine. It work isn't good: sometimes work, sometimes doesn't and sometimes throw error "QObject::setParent: Cannot set parent, new parent is in a different thread".
If Qt has API to send event, it may help: in resizeMainWindow() add timer that will send event 'resize', then process the event. Between set timer and timer event the main window will be maximized and resizeByTimer() will work properly.

@damanis
Copy link
Author

damanis commented Dec 3, 2022

@akiyosi
QT does have closed issue about inconsistent window state in resizeEvent: QTBUG-30085.
The main reason of undefined window state: 'it depends very much on the underlying windowing system'.
The simple workaround is save old size in resizeEvent, then use it if maximized event appears. Another way - handle changeEvent.

@akiyosi
Copy link
Owner

akiyosi commented Dec 4, 2022

@damanis
Thanks for this info.
I may not be understanding the workaround correctly, but I think the way to save the old window size when emitting a resizeevent does not solve the problem, as the animation during window maximization causes a number of resizeevents to be emitted.

I tried add timer after WindowGeometryBasedOnFontmetrics checking and put rest code to goroutine. It work isn't good: sometimes work, sometimes doesn't and sometimes throw error "QObject::setParent: Cannot set parent, new parent is in a different thread".
If Qt has API to send event, it may help: in resizeMainWindow() add timer that will send event 'resize', then process the event. Between set timer and timer event the main window will be maximized and resizeByTimer() will work properly.

Could you provide me with the above fixes, if possible? This way seems to me to be the most practical.

@akiyosi
Copy link
Owner

akiyosi commented Dec 5, 2022

@damanis
I was inspired with your idea and I think we are getting closer to a solution to this problem.
I have pushed one branch to improve this problem.

#426

@damanis
Copy link
Author

damanis commented Jul 7, 2023

@akiyosi
I think, this solution should work:

  • add struct to store current and previous window size struct { current_size; previous_size; maximized: bool; }

  • in resize handler copy current_size to previous_size (in addition to current code)

  • in maximize handler set maximized to true

  • in next resize or unmaximize restore window size to previous_size if maximized is true. Set maximized to false.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants