WinMove for window resize is "flickery"

Get help with using AutoHotkey and its commands and hotkeys
nickstokes
Posts: 8
Joined: 05 Nov 2015, 18:24

WinMove for window resize is "flickery"

05 May 2018, 21:34

Using WinMove to adjust window size in a loop causes the window to flicker. I uploaded the exact effect in developed conversation below, and contrasted with the smooth behavior of regular window-edge mouse-drag resize behavior.

The loop in question is like so:

Code: Select all

; ...
SetWinDelay, 0
while(GetKeyState("RButton","P"))
{  
  MouseGetPos, mx, my

  deltaX := mx - mx0
  deltaY := my - my0

  WinMove ahk_id %window_id%,, wx-deltaX, wy-deltaY, ww, wh
}
See the full code in one of my below comments.

Is there a remedy?

Thanks

PS: This post is edited heavily after useful feedback from the forum.
Last edited by nickstokes on 09 May 2018, 07:03, edited 1 time in total.
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: WinMove for window resize is "flickery"

06 May 2018, 23:53

you can post message WM_SYSCOMMAND with SC_SIZE to the window. That will have the effect, like try in notepad, of clicking the Size menu in the window system menu. basically you wont have to do anything but send/post that message once

https://msdn.microsoft.com/en-us/librar ... s.85).aspx
nickstokes
Posts: 8
Joined: 05 Nov 2015, 18:24

Re: WinMove for window resize is "flickery"

07 May 2018, 08:09

icuurd12b42 wrote:you can post message WM_SYSCOMMAND with SC_SIZE to the window. That will have the effect, like try in notepad, of clicking the Size menu in the window system menu. basically you wont have to do anything but send/post that message once
You mean this:

Code: Select all

PostMessage,  0x0112, 0xF000, 0, , ahk_id %window_id%
which is equivalent to,

Code: Select all

WinMenuSelectItem, ahk_id %window_id%,,0&, Size
?

I am not quite sure if this has the interactive effect I am shooting for. It needs a subsequent arrow key input and mouse drag. Imagine the right hand being on the mouse, lifting up back to keyboard to strike an arrow-combo, then back to the mouse again. This is "tedious". I suspect a creative solution is possible that relies on this (would love to get my hands on one), but just sending the message isn't sufficient I am afraid.

The script I am hoping to achieve helps with many-windows-on-a-large-4K-monitor workflow, where windows are moved and resized with ease, especially those that don't present an easy way to resize/move (for example do you ever use the "post-it" mode on Notepad++?). Basically the following:

0. Left hand is on the keyboard, right hand is on the mouse, moving around windows.
1. Left hand presses a convenient key combination, and mouse right-click-drag resizes the window it is hovering over. (left-click-drag moves the window)
2. The initial move in the mouse determines which corner or edge to drag around.
3. Mouse button release terminates the loop

Here is a my attempt at a script that accomplishes this - very ugly and does not quite "feel right", but works to the extent that I still prefer this over menu-resize. And currently, one issue is this WinMove based resize flickering:

Code: Select all

; ctrl+alt while right-click drag to resize the window
^!RButton::
CoordMode, Mouse, Screen
MouseGetPos, mx0, my0, window_id
WinGetPos, wx, wy, ww, wh, ahk_id %window_id%
WinGet, window_minmax, MinMax, ahk_id %window_id%

; Restore the window if maximized
if (window_minmax > 0)
{
  WinRestore ahk_id %window_id%
}

SetWinDelay, 0

firstDeltaX := "init"
firstDeltaY := "init"

while(GetKeyState("RButton","P")) {  
  ; resize the window based on cursor position
  MouseGetPos, mx, my
  if(mx == mx0 && my == my0) {
     continue
  }

  if( firstDeltaX == "init" && mx-mx0 <> 0 ) {
     firstDeltaX := mx-mx0
  }
  if( firstDeltaY == "init" && my-my0 <> 0 ) {
     firstDeltaY := my-my0
  }
  
  deltaX := mx - mx0
  deltaY := my - my0
  
  if(firstDeltaX<0) {
     ww += deltaX
  }
  else if (firstDeltaX>0) {
	 wx += deltaX
	 ww -= deltaX
  }
  if(firstDeltaY<0) {
     wh += deltaY
  }
  else if (firstDeltaY>0) {
	 wy += deltaY
	 wh -= deltaY
  }
 
  mx0 := mx
  my0 := my
  
  WinMove ahk_id %window_id%,, wx, wy, ww, wh
}
return

For left-click-drag window move I am using this neat script by Lasmori, which was also the inspiration for the above.

Any other ideas are very much appreciated!

Thanks for the help.
User avatar
jeeswg
Posts: 6816
Joined: 19 Dec 2016, 01:58
Location: UK

Re: WinMove for window resize is "flickery"

07 May 2018, 09:43

- So, are you saying that this q subroutine causes some kind of flickering, but that the w subroutine doesn't?
- What OS are you using? Cheers.

Code: Select all

q:: ;move up/left
WinGetPos, vWinX, vWinY, vWinW, vWinH, A
WinMove, A,, % vWinX-5, % vWinY-5, % vWinW, % vWinH
return

w:: ;shrink up/left
WinGetPos, vWinX, vWinY, vWinW, vWinH, A
WinMove, A,, % vWinX, % vWinY, % vWinW-5, % vWinH-5
return

e:: ;resize
vWinX := vWinY := vWinW := vWinH := 300
WinMove, A,, % vWinX, % vWinY, % vWinW, % vWinH
;SetWinDelay, 0
return
- Btw you could record the last hWnd/position in the function (define them as static variables), and if the window is the same as last time and is already in the right position, to skip the WinMove. Thus the window moving would only occur when it needed to.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
nickstokes
Posts: 8
Joined: 05 Nov 2015, 18:24

Re: WinMove for window resize is "flickery"

09 May 2018, 06:58

Helgef wrote:Try setwindelay -1
This does not help I am afraid.

jeeswg wrote: So, are you saying that this q subroutine causes some kind of flickering, but that the w subroutine doesn't?
You're right, I take that back. It must have been a false assumption bias. With better testing (and eyes!) I see the flickering in either direction. I'll rephrase the original question as well.
jeeswg wrote: Btw you could record the last hWnd/position in the function (define them as static variables), and if the window is the same as last time and is already in the right position, to skip the WinMove. Thus the window moving would only occur when it needed to.
Not sure I understand what you mean? The resizing occurs in a mouse-drag loop *continuously* and with repeated application per design (that is kind of the whole point of the script). There is already the zero guard in the second line of the

Code: Select all

while
-block. Where exactly would the static variables help?

Here are a couple of screenshots to explain the behavior, also demonstrate the flicker affect.

ahk-resize-script.gif
My script: A number of right-click drags to resize and left-click drags to move to resize and relocate the window to taste. Notice how the tabs disappear while resizing and the scroll bars etc flicker. This gif is captured at 20fps. In real-time it is worse.
ahk-resize-script.gif (806.06 KiB) Viewed 1153 times
ahk-resize-regular.gif
Using window edge left-click drag to resize. Notice the smoothness. (but exceptionally painful to hover the mouse to within 1-px tolerance of drag corner, esp upper right - ouch!)
ahk-resize-regular.gif (814.76 KiB) Viewed 1153 times
User avatar
jeeswg
Posts: 6816
Joined: 19 Dec 2016, 01:58
Location: UK

Re: WinMove for window resize is "flickery"

09 May 2018, 07:46

- Even with the built-in Explorer resizing (dragging on the corners etc) it appears to flicker.
- Perhaps you could disable the windows or prevent them from refreshing.
- Perhaps you could use a selection rectangle, to show where the rectangle will end up when you release it. My script shades the whole area, the other script, that I link to, shades a rectangular outline.
selection rectangle: use mouse to select screen region - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=42810
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: WinMove for window resize is "flickery"

10 May 2018, 18:51

You can try to send a redraw now message to the window with the
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
win api...

you can also disable the drawing Sending a WM_SETREDRAW message with 0 for disabled and 1 for enable to the window.
User avatar
Drugwash
Posts: 737
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania

Re: WinMove for window resize is "flickery"

11 May 2018, 03:54

Try using SetWindowPos() with different combination of flags, instead of WinMove:

Code: Select all

; 0x4000	= SWP_ASYNCWINDOWPOS
; 0x2000	= SWP_DEFERERASE
; 0x400		= SWP_NOSENDCHANGING
; 0x200		= SWP_NOOWNERZORDER
; 0x100		= SWP_NOCOPYBITS
; 0x10		= SWP_NOACTIVATE
; 0x8			= SWP_NOREDRAW
; 0x4			= SWP_NOZORDER
DllCall("user32\SetWindowPos"
	, "Ptr", window_id
	, "Ptr", 0
	, "Int", wx
	, "Int", wy
	, "Int", ww
	, "Int", wh
	, "UInt", 0x4214)
Not sure if it would make a difference but you may also send
SendMessage, 0x231, 0, 0,, ahk_id %window_id% ; WM_ENTERSIZEMOVE
just before entering the While loop, and then
SendMessage, 0x232, 0, 0,, ahk_id %window_id% ; WM_EXITSIZEMOVE
immediately after exiting the loop.
I also tried sending WM_SIZING instead of SetWindowPos() but unfortunately the target window does not respond to it:

Code: Select all

VarSetCapacity(RECT, 16, 0)
NumPut(wx, RECT, 0, "Int"), NumPut(wy, RECT, 4, "Int")
NumPut(ww+wx, RECT, 8, "Int"), NumPut(wh+wy, RECT, 12, "Int")
SendMessage, 0x214, 8, &RECT,, ahk_id %window_id%	; WM_SIZING
and besides the drag origin must be calculated; above I arbitrarily used WMSZ_BOTTOMRIGHT=8 for testing purposes.
I've deleted my CloudMe account because of GDPR - the now legal base for privacy invasion and data theft.
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: WinMove for window resize is "flickery"

12 May 2018, 08:25

re-visiting my syscommand message suggestions

>I am not quite sure if this has the interactive effect I am shooting for. It needs a subsequent arrow key input and mouse drag. Imagine the right hand being on the mouse, lifting up back to keyboard to strike an arrow-combo, then back to the mouse

why not send the correct arrow key after SENDING (not POSTING) the sys command message? it should in theory result in the same thing as you video, aside the fact the mouse will snap to the appropriate border...
nickstokes
Posts: 8
Joined: 05 Nov 2015, 18:24

Re: WinMove for window resize is "flickery"

16 Oct 2018, 09:15

I finalized this, not perfect but useful nevertheless. Thank you all very much for the help and recommendations.

Code shared here: https://autohotkey.com/boards/viewtopic.php?f=6&t=57703

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], flyingDman, Google [Bot], MSN [Bot], spectequila and 178 guests