Re: emacs holding focus, not granting it to xterm
On 6/27/2014 11:22 PM, alflanagan wrote: > The problem occurs when I run emacsclient to connect to an existing instance > of emacs; the file shows up in emacs and emacsclient exits as expected, but > focus remains "stuck" in emacs for some time. I tried the following to reproduce the problem: Under Cygwin X Server Version 1.15.1-3: 1.) Start an xterm under cygwin with xserver in multiwindow mode. 2.) From this cygwin xterm log into remote linux (debian 3.2.0-4-486) machine with "ssh -X". 3.) After logged in to the remote linux machine: start emacs with "emacs &". This opens a new X11 window under cygwin X server which is on top and has keyboard focus. 4.) In Emacs Window type the key combination Alt+X and then "server-start" 5.) Go back to xterm window and type: "emacsclient &" to edit the file in the emacs-server. 6.) Now: all typing goes inte the emacs X11 window, although this window is in the background (it might even be not visible if it is behind other windows). It turns out that the above behaviour is the known problem that windows are not raised from the Cygwin X Server in multiwindow mode, if a program wants to programmatically activate a window as reported in http://www.cygwin.com/ml/cygwin-xfree/2005-06/msg00072.html . If I start a modified xserver with my patch applied from https://cygwin.com/ml/cygwin-xfree/2011-08/msg00034.html the following happens in step 6: 6'.) the emacs window is raised to the top over all windows and gets the keyboard focus. I think that 6'.) is the expected behaviour because this also happens if running under a x server on a linux machine instead of cygwin. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
problem evaluating window resize hints under 64 bit
The current cygwin x server 1.15.1-2 under 64-bit cygwin seems to have a problem correctly evaluating the window resize hints. In hw/xwin/winmultiwindowwndproc.c the function ValidateSizing calls winMultiWindowGetWMNormalHints and gets wrong values in sizeHints.width_inc and sizeHints.height_inc. In function winMultiWindowGetWMNormalHints in file hw/xwin/winmultiwindowclass.c you can see that a memcpy occurs from prop->data with sizeof(WinXSizeHints). As it turns out, everything is correct if you modify the typedef of WinXSizeHints in hw/xwin/winmultiwindowclass.h so that long type becomes int: --- a/cygwin/hw/xwin/winmultiwindowclass.h +++ b/cygwin/hw/xwin/winmultiwindowclass.h @@ -63,7 +63,7 @@ typedef struct { * used with WM_NORMAL_HINTS. */ typedef struct { -long flags; /* marks which fields in this structure are defined */ +int flags; /* marks which fields in this structure are defined */ int x, y; /* obsolete for new window mgrs, but clients */ int width, height; /* should set so old wm's don't mess up */ I can only guess why this works: in the X11 message protocol all int and long types are mapped to 32 bit integers. It seems that the memcpy in winMultiWindowGetWMNormalHints has source data that has memory layout as in the X11 message protocol. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: XRaiseWindow for activating windows in multiwindow mode
On 6/11/2014 10:50 PM, Patrick Herbst wrote: On 03 Sep 2011, Jon TURNEY wrote: On 13/08/2011 19:39, Oliver Schmidt wrote: as reported in http://www.cygwin.com/ml/cygwin-xfree/2005-06/msg00072.html windows are not raised from the Cygwin X Server in multiwindow mode, if a program wants to programmatically activate a window. I played around and figured out that the problem can be solved by ... I enclose the patch in this email. It works fine for me, but ... Is there a fix planned for this? I too use applications that make use of XRaiseWindow to navigate around multiple windows, and it doesn't work. Anyone have any info on this issue?? I used my patch from 2011 every day for the last three years and it worked always without any problems. I was also able to incorporate this patch into the newest cygwin x server running under 64-bit cygwin without any problems. See also: https://cygwin.com/ml/cygwin-xfree/2011-08/msg00034.html https://cygwin.com/ml/cygwin-xfree/2011-09/msg0.html https://cygwin.com/ml/cygwin-xfree/2011-09/msg3.html I don't understand, why this patch was not included into the official cygwin-x-server. Of course it would be nice, if a better solution was available. For pragmatic reasons it would be nice to include this patch into official cygwin x server until a better solution is available. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: considering modifier keys after gaining focus
On 1/12/2012 1:19 PM, Oliver Schmidt wrote: > On 1/11/2012 6:16 PM, Jon TURNEY wrote: >> Hm... on looking at this again, isn't that code you are adding checking the >> internal state of non-latching modifiers bogus? If we release all keys on >> WM_KILLFOCUS, then the non-latching modifiers will always be clear when the >> WM_SETFOCUS occurs, so we will always generate the keypress for the modifier. > > Yes, my patch also generates key release events for modifiers despite > the fact, that all modifier have been released after the xserver looses > the window focus. When writing the patch, I wasn't sure if this is > always the case, so I made the code a little bit more "robust" in the > sense that it tries to correct the modifier keys in any case (so it will > always work, even if something goes wrong in other code locations). My answer is perhaps a little bit unexact. To be more precise: +BOOL ctrl = (GetAsyncKeyState (VK_CONTROL) < 0); +if (WIN_XOR (internalKeyStates & ControlMask, ctrl)) + winSendKeyEvent (KEY_LCtrl, ctrl); The above code fragment will send a key press event for the ctrl key, if the current "real" ctrl modifier state is pressed and differs from the xserver's internal key state for ControlMask. It will send a key release event for the ctrl key, if the current "real" ctrl modifier state is "not pressed" and differs from the xserver's internal key state for ControlMask. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: considering modifier keys after gaining focus
Hi Jon, On 1/11/2012 6:16 PM, Jon TURNEY wrote: > I think it is useful to consider this history when reviewing a patch, > Are we going in circles? Are we doing in the wrong direction? I appreciate your carefulness und thoroughness. It's of course always better to understand what is going on, especially in a large code base with a long history. > Anyhow, in a brief look at some mailing list discussions from 2002 or so, it > seems that: > i) We must release modifier keys when focus leaves the X server, as modifier > keys may be part of a Windows shell shortcut which moves the focus elsewhere, > e.g. alt-tab) so the key-release isn't received by the X server. Ah ok, so my guess was in the right direction ;-) > ii) We must release non-modifier keys when focus leaves the X server, or they > continue to auto-repeat in the X server (specifically a problem when a > key-press closes a window (such as typing ctrl-d or exit into an Xterm), as > the key-release goes to the next window to receive focus, which may not be an > X window) Interesting, I didn't know this. Thank you for figuring this out from the malinglists archives. > iv) What should we do about held non-modifier keys when focus enters the X > server? > > It looks like these should be pressed as well for strict correctness. If we > hold down a non-modifier key so it auto-repeats, and move the focus between X > and native windows, the native windows receive repeats, but the the X windows > do not. I doubt many people care about this behaviour, though :-) Yes, you are right: I can reproduce this phenomenon by holding down Ctrl+N for opening windows and the key is not autorepeated (so only one window is opened, whereas under Linux xserver many windows are opened). In my daily usage I didn't discover this phenomenon. My patch only addresses the problem, that the modifier keys are not right after keyboard driven focus change, disrupting my workflow. So I agree that there might not many people caring about this behaviour. > Hm... on looking at this again, isn't that code you are adding checking the > internal state of non-latching modifiers bogus? If we release all keys on > WM_KILLFOCUS, then the non-latching modifiers will always be clear when the > WM_SETFOCUS occurs, so we will always generate the keypress for the modifier. Yes, my patch also generates key release events for modifiers despite the fact, that all modifier have been released after the xserver looses the window focus. When writing the patch, I wasn't sure if this is always the case, so I made the code a little bit more "robust" in the sense that it tries to correct the modifier keys in any case (so it will always work, even if something goes wrong in other code locations). Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: XWIN-1.11.3.0 crashes when some client programs terminate.
Hi, On 1/10/2012 5:01 AM, rodmed...@cantv.net wrote: > I am attaching the sources of a > simple program that consistently produces the crash of the server. I compiled your program using the commandline: gcc -I. paneltest.c xbutton.c xinitapp.c xinline.c \ xinpanel.c xwinutil.c -lx11 in the src directory of your expanded archive. How can the crash be reproduced? If I leave the program by closing the window no crash occurs. > With the last release of Xwin (1.11.3.0) I have found the following > problem. I'm using the current cygwin xorg-server version 1.11.3-1, perhaps the problem has been fixed? Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: considering modifier keys after gaining focus
It's me again ;-) On 1/10/2012 10:47 AM, Oliver Schmidt wrote: > Ok, I tried using "GetKeyState" instead of "GetAsyncKeyState" and it > also works. So it seems to be a good idea to switch to "GetKeyState". My answer was too fast: unfortunately I got problems using "GetKeyState" instead of "GetAsyncKeyState": I had hanging Alt-Keys if switching into a x11 window using alt+tab when the mouse was already in the window before the alt+tab keypress. So I switched back to using "GetAsyncKeyState" and everything now works again as it should. So after my experience we should use "GetAsyncKeyState": this works for me without any problems since August 2011 and I'm using this 8 hours every day, doing a lot of keyboard stuff and opening, raising and closing X11 windows frequently using the keyboard. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: considering modifier keys after gaining focus
Hi, On 1/9/2012 7:11 PM, Oliver Schmidt wrote: > NEdit, press Ctrl+N for a new window, hold the Ctrl key and press S > (i.e. Ctrl+S) for saving. For the above NEdit example you have to disable the entry "Preferences / Default Settings / Tabbed Editing / Open File In New Tab" from NEdit's menu bar. Otherwise Ctrl+N will not open a new window. Of course every keyboard driven program that opens new windows with keyboard shortcuts will have problems with lost modifier key state. Moreover, if using my patch for "programmatically raising top level windows" ( http://cygwin.com/ml/cygwin-xfree/2011-08/msg00034.html ) the problem also occurs if a application raises windows by keyboard shortcuts. > I will try using GetKeyState tomorrow. I just wanted to be sure to get > the current key state when the window gets the focus. Ok, I tried using "GetKeyState" instead of "GetAsyncKeyState" and it also works. So it seems to be a good idea to switch to "GetKeyState". Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: Why doesn't M-C-s work for me?
Hi Mark, On 09.01.2012 19:32, Mark Geary wrote: > --s (will abbreviate as M-C-s from here-on) does > nothing for me. Does anyone have any thoughts on why it might not be working? > I have the left control and the caps lock keys swapped with a > registry edit: does this problem also occur with normal windows programs? I have also made the caps lock key to a ctrl key and I cannot press ctrl+shift+s when using the "caps lock" key as ctrl key. So it seems for me that on some keyboards some key combinations of more than two keys at the same time are not possible (perhaps due to technical implementation details?) Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: considering modifier keys after gaining focus
Hi Jon, On 09.01.2012 15:06, Jon TURNEY wrote: > I have a few questions and comments below: > >> Example: in window A Ctrl + some key opens a window B, then in window B >> Ctrl + some other key triggers the next action. However after the opening >> of window B the Ctrl key has to be released and pressed again. If the user >> keeps the Ctrl key holding when the window B is opened, the next key press >> X will be interpreted as X and not as Ctrl+X. > > Can you give an example of an application where this causes a problem, so I > can test your patch? because current cygwin x-server is not able to raise windows, you could only test the case, that a new window is created. Any X11 program that can create windows and has keyboard shortcuts will do it, e.g. take NEdit, press Ctrl+N for a new window, hold the Ctrl key and press S (i.e. Ctrl+S) for saving. > The code would seem to end up simpler (which is an important consideration) if > we were to modify winKeybdReleaseKeys() not to release modifier keys. Some > archaeology is probably required to determine if releasing the modifier keys > in winKeybdReleaseKeys() is necessary to avoid some other undesirable > behaviour? I don't know anything about the cygwin X server history, I can only guess why the current code is as it is: Perhaps the modifier keys are released afer loosing a window's focus because if another Non-cygwin window gains the focus, no more modifier change events will arrive to the cygwin x server. > This also begs the question why is it only necessary to press some some subset > of the down keys on WM_SETFOCUS? Does the X server behave correctly if a > non-modifier key is held down while focus moves from one X server window to > another, or from one X server window to a native window an back? My code simply updates the xserver's internal state about the modifier keys after gaining the window focus. Other keys behave correctly, because the xserver doesn't have an internal state for them. > Why is is correct to use GetAsyncKeyState() here and not GetKeyState()? If we > use GetAsyncKeyState() there may be a message pending (See the remarks on > GetKeyState() in MSDN) to change to the key state, so we might conceivably > double the key press? I will try using GetKeyState tomorrow. I just wanted to be sure to get the current key state when the window gets the focus. > This maps VK_CONTROL to KEY_LCtrl. Why not use VK_LCONTROL and VK_RCONTROL, > so the generated key-press is for the correct key? > Ditto for VK_LSHIFT and VK_RSHIFT Perhaps this might improve the patch, however the internal modifier state of the xserver has only ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask. So the internal state does not distinguish betweem left or right shift key. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: considering modifier keys after gaining focus
Hi, On 8/16/2011 5:31 PM, Oliver Schmidt wrote: > I had the problem, that the state of the modifier keys was lost when a > window is created (or raised). > I send a patch to fix this problem with this email: I just extended the I just merged the current official source from xorg-server-1.11.3-1 into my local development source and discovered, that my patch for the problem "lost modifier key after a new window is created" has not been applied. Is there a chance, that this patch could be applied to a future version or that another solution could be provided to fix this problem? I'm also attaching a newer version of the patch with this email. Best regards, Oliver diff --git a/cygwin/hw/xwin/winkeybd.c b/cygwin/hw/xwin/winkeybd.c index 278342f..a2ac4d0 100644 --- a/cygwin/hw/xwin/winkeybd.c +++ b/cygwin/hw/xwin/winkeybd.c @@ -283,6 +283,29 @@ winRestoreModeKeyStates (void) * have a logical XOR operator, so we use a macro instead. */ + { +/* consider modifer keys */ + +BOOL ctrl = (GetAsyncKeyState (VK_CONTROL) < 0); +BOOL shift = (GetAsyncKeyState (VK_SHIFT) < 0); +BOOL alt= (GetAsyncKeyState (VK_LMENU) < 0); +BOOL altgr = (GetAsyncKeyState (VK_RMENU) < 0); + +if (ctrl && altgr) ctrl = FALSE; + +if (WIN_XOR (internalKeyStates & ControlMask, ctrl)) + winSendKeyEvent (KEY_LCtrl, ctrl); + +if (WIN_XOR (internalKeyStates & ShiftMask, shift)) + winSendKeyEvent (KEY_ShiftL, shift); + +if (WIN_XOR (internalKeyStates & Mod1Mask, alt)) + winSendKeyEvent (KEY_Alt, alt); + +if (WIN_XOR (internalKeyStates & Mod5Mask, altgr)) + winSendKeyEvent (KEY_AltLang, altgr); + } + /* Has the key state changed? */ dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001; if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState)) @@ -328,7 +351,7 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) MSG msgNext; LONG lTime; Bool fReturn; - + static Bool lastWasControlL = FALSE; static UINT lastMessage; static LONG lastTime; -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: XRaiseWindow for activating windows in multiwindow mode
On 10/21/2011 1:43 PM, Michel Hummel wrote: > Can I know the exact patch list applied to generate it ? you can see the source code of my current playground version at https://github.com/osch/cygwin-xserver Commit 1ec241341cf1c85abf0372e00ae9acc8be66894b contains the official sources from xserver-cygwin-1.10.3-1. I'm also attaching a patch file of my current version against xserver-cygwin-1.10.3-1 to this email. Best regards, Oliver diff --git a/cygwin/dix/dispatch.c b/cygwin/dix/dispatch.c index 44f8087..18e9697 100644 --- a/cygwin/dix/dispatch.c +++ b/cygwin/dix/dispatch.c @@ -343,33 +343,27 @@ DisableLimitedSchedulingLatency(void) #define MAJOROP ((xReq *)client->requestBuffer)->reqType -void -Dispatch(void) -{ -int*clientReady; /* array of request ready clients */ -intresult; -ClientPtr client; -intnready; -HWEventQueuePtr* icheck = checkForInput; -long start_tick; +static int*clientReady; /* array of request ready clients */ +static int result; +static ClientPtr client; +static int nready; +static HWEventQueuePtr* icheck = checkForInput; +static longstart_tick; -nextFreeClientID = 1; -nClients = 0; - -clientReady = malloc(sizeof(int) * MaxClients); -if (!clientReady) - return; - -SmartScheduleSlice = SmartScheduleInterval; -while (!dispatchException) -{ +int DispatchOneStep(Bool handleWindowMessage) +{ +int rslt = 0; + if (*icheck[0] != *icheck[1]) { ProcessInputEvents(); FlushIfCriticalOutputPending(); } - nready = WaitForSomething(clientReady); + rslt = nready; + +if (handleWindowMessage) +handleNextWindowMessage(); if (nready && !SmartScheduleDisable) { @@ -460,6 +454,24 @@ Dispatch(void) client->smart_stop_tick = SmartScheduleTime; } dispatchException &= ~DE_PRIORITYCHANGE; + +return rslt; +} + +void +Dispatch(void) +{ +nextFreeClientID = 1; +nClients = 0; + +clientReady = malloc(sizeof(int) * MaxClients); +if (!clientReady) + return; + +SmartScheduleSlice = SmartScheduleInterval; +while (!dispatchException) +{ +DispatchOneStep(TRUE); } if (ddxHooks.ddxBeforeReset) diff --git a/cygwin/hw/xwin/winkeybd.c b/cygwin/hw/xwin/winkeybd.c index 9e5a9b0..99c822d 100644 --- a/cygwin/hw/xwin/winkeybd.c +++ b/cygwin/hw/xwin/winkeybd.c @@ -282,6 +282,29 @@ winRestoreModeKeyStates (void) * have a logical XOR operator, so we use a macro instead. */ + { +/* consider modifer keys */ + +BOOL ctrl = (GetAsyncKeyState (VK_CONTROL) < 0); +BOOL shift = (GetAsyncKeyState (VK_SHIFT) < 0); +BOOL alt= (GetAsyncKeyState (VK_LMENU) < 0); +BOOL altgr = (GetAsyncKeyState (VK_RMENU) < 0); + +if (ctrl && altgr) ctrl = FALSE; + +if (WIN_XOR (internalKeyStates & ControlMask, ctrl)) + winSendKeyEvent (KEY_LCtrl, ctrl); + +if (WIN_XOR (internalKeyStates & ShiftMask, shift)) + winSendKeyEvent (KEY_ShiftL, shift); + +if (WIN_XOR (internalKeyStates & Mod1Mask, alt)) + winSendKeyEvent (KEY_Alt, alt); + +if (WIN_XOR (internalKeyStates & Mod5Mask, altgr)) + winSendKeyEvent (KEY_AltLang, altgr); + } + /* Has the key state changed? */ dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001; if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState)) @@ -327,6 +350,12 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) MSG msgNext; LONG lTime; Bool fReturn; + + static Bool hasLastControlL = FALSE; + static UINT lastMessage; + static WPARAM lastWparam; + static LPARAM lastLparam; + static LONG lastTime; /* * Fake Ctrl_L presses will be followed by an Alt_R keypress @@ -360,9 +389,22 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) WM_KEYDOWN, WM_SYSKEYDOWN, PM_NOREMOVE); } - if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN) + if (fReturn && msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN) fReturn = 0; + if (!fReturn) +{ + hasLastControlL = TRUE; + lastMessage = message; + lastWparam = wParam; + lastLparam = lParam; + lastTime= lTime; +} + else +{ + hasLastControlL = FALSE; +} + /* Is next press an Alt_R with the same timestamp? */ if (fReturn && msgNext.wParam == VK_MENU && msgNext.time == lTime @@ -377,11 +419,33 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) } } + /* + * Check for Alt_R keypress, that was not ready when the + * last Ctrl_L appeared. + */ + else if ((message == W
Re: XRaiseWindow for activating windows in multiwindow mode
Hi Michel, On 10/19/2011 11:33 AM, Michel Hummel wrote: > I am a bit late but I will be happy to test this version of XWin. > Could you give me a patched binary version please ? You can download my currently used version of XWin.exe from: http://min.us/mgtjlVdju This version includes also my other patches (e.g. experimental redrawing of windows while they are resized/moved, see http://www.cygwin.com/ml/cygwin-xfree/2011-08/msg00049.html). I'm using this version daily, so it can be considered stable for my personal usage patterns ;-) However if the redrawing patch causes problem on your setup I could prepare a version without this patch. For me the most missing feature from the official Cygwin's x-server is the possibility to programmatically raise windows in multi window mode, so I'm happy to hear that others are interested in this feature too. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: redraw windows while resizing/moving windows in multiwindow mode
Hi Jon, On 9/7/2011 5:05 PM, Jon TURNEY wrote: > This is fine as a proof of concept, and it would be nice to handle this did you try the patch? It looks & feels very smooth if you resize a xlock and the xclock and all x11 background windows are redrawn while resizing ;-) > better and do X window updates during the Windows modal resizing loop, > but I don't think I can apply this patch. but I hope this patch can be used as a starting point. > Well, in fact, no X events are processed while in the modal resizing > loop, so for e.g. if you have ico running in another X window, it stops > updating while an xterm window is being resized. with the patch X events are processed. With the patch, ico redraws also while windows are moved or resized, as long as the mouse is moved. For display updating without moving the mouse while modal resizing/moving is in progress, I already mentioned the timer event that is possible to improve the patch. Thanks for mentioning "ico", I didn't know this program, it is an interesting experimental tool: it shows that the patch is too aggressive, i.e. the ui interface is not responsive, perhaps due to my "critical" code fragment: while (DispatchOneStep(FALSE) > 0) {} So I will try now to improve the patch for better responsiveness. > Note that there are other modal loops in Windows message handling, I > think moving the scrollbar also involves one (which can happen in > windowed mode with the -scrollbar option) One could introduce a similar patch there too ;-) However a patch for scrollbar option in windowed mode is not as reasonable as in multiwindow mode, because the static redrawing of the x server makes sense in windowed mode. Only in multiwindow mode the redrawing is strange, e.g. if you applied my patch "minimize redraw events after resizing/moving windows in multiwindow mode", you will see other X11 background windows while "resizing" a x11 foreground window in the window that is resized, because actually the x11 window is not resized due to missing x11 event processing, but the xserver simply redraws all x11 windows in the current size. In windowed mode, no x11 window is resized. > I'm not sure how to structure the change to Dispatch() in a way which > would be acceptable upstream. I hoped, you had an idea. What are the criteria to be accepted upstream? At least the patch introduces only a "bypass", i.e. existing code/usage is not affected. It would be discouraging if no upstream changes are possible to improve the cygwin x server's multi window mode, since this is the mode that allows the highest integration of x11 applications with native windows programs. If no upstream changes are possible one fallback could be to have a local patch (or #ifdef switch) for the cygwin x server. > An additional point to consider is that you may have introduced the > possibility of re-entrancy into either the X window message dispatcher, > or the Windows message dispatcher, which may not be safe. (e.g. > winTopLevelProc -> DispatchOneStep -> (some X event processing calls a > DDX function which calls SendMessage) -> winTopLevelProc ...) Could you explaind this more explicitly? How can this be tested? As I understood the code, the function "Dispatch" is only called once per x server invocation. And the new function "DispatchOneStep" is meant to be processed re-entrant. This is why the boolean parameter handleWindowMessage is introduced and why I had to remove the invocation of DispatchMessage out of the winWakeupHandler which is called in WaitForSomething. > An alternative approach would be to move the Windows message pump into a > separate thread from the X server message dispatch. Unfortunately, this > would probably involve rather major changes, and careful examination of I agree that this would cause a lot of more work than the approach of my patch. I'm not sure if moving the Windows message handling into a different thread will solve the problem totally: there still is the problem, that in the modal windows event loop the x11 event processing must be invoked. At least one has to totally decouple the x11 and Windows event processing, but then still in the modal event loop the now decoupled x11 processing must be triggered. So it seems to me, that decoupling the x11 and Windows processing does only prevent upstream changes but does not solve the problem, that in the modal Windows event loop small progressing parts for X11 (coupled or decoupled) have to be done. > Alternatively, it might be worth investigating to see if it is possible > to use a message filter set with SetWindowsHookEx(WH_MSGFILTER) to run > the X window dispatch while Windows is in a modal loop? I'm not sure if I'm understanding this approach correctly, but I think even with SetWindowsHookEx we still have the problem, that the main loop in Dispatch has to be broken into smaller parts that can be invoked from inside the modal Windows event loop (or hook). Best regards, Oliver -- Unsubscribe inf
Re: AltGr key mostly fires an additional CONTROL key
Hi Jon, On 9/5/2011 3:35 PM, Jon TURNEY wrote: > comments, as what this code is trying to do is slightly obscure, and I > assume that the old comments about TweakUI being the cause of this are > just wrong (as you don't mention that you have it installed) Yes I didn't test it with Tweak UI and I ignored the comments on Tweak UI. I also think that the old "sleep(0)" workaround for Tweak UI is now not necessary with the new patch. But I kept the changes as minimal as possible and tried to keep existing code as much as it is. >> diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c >> + static Bool hasLastControlL = FALSE; >> + static UINT lastMessage; >> + static WPARAM lastWparam; >> + static LPARAM lastLparam; >> + static LONG lastTime; > > I was going to suggest using static MSG lastMsg, but then I noticed > that lastWparam, lastLparam are completely unused... yes, they are now unused editing relicts from my testing phase... >> + >> + if ((lastMessage == WM_KEYDOWN || lastMessage == >> WM_SYSKEYDOWN) >> + && lastTime == lTime) > > Why is it necessary to check that the last message was WM_(SYS)KEYDOWN > here? hasLastControlL can't get set unless it was? yes you are right: the if condition here is a little over-determined ;-) >> diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c >> + /* Discard fake Ctrl_L presses that precede AltGR on non-US >> keyboards */ >> + if (winIsFakeCtrl_L (message, wParam, lParam)) >> +return 0; >> + >> - /* Discard fake Ctrl_L presses that precede AltGR on non-US >> keyboards */ >> - if (winIsFakeCtrl_L (message, wParam, lParam)) >> -return 0; >> - > > Can you say why it's necessary to change the order here and why this is > the correct ordering? A comment here might be a good idea :-) in the old coding there is this check for generated Windows auto-repeat key events and this check can cause the function to exit: /* * Discard presses generated from Windows auto-repeat */ if (lParam & (1<<30)) { switch (wParam) { /* ago: Pressing LControl while RControl is pressed is * Indicated as repeat. Fix this! */ case VK_CONTROL: case VK_SHIFT: if (winCheckKeyPressed(wParam, lParam)) return 0; break; default: return 0; } } I didn't change this coding and I'm not sure what the funtion winCheckKeyPressed exactly does. However the check winIsFakeCtrl_L must be done before leaving the function because of auto-repeated key events. Otherwise there will be problems with autorepeated AltGr-Keys. These must also be tracked with winIsFakeCtrl_L otherwise autorepeated AltGr keys could produce a "hanging" Control_L key (I had this effect when I tested the patch). So the order has to be changed, because the function winIsFakeCtrl_L now has an internal state due to it's static variables and this state has to be synchronized with the actuel key events. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: XRaiseWindow for activating windows in multiwindow mode
It's me again ;-) On 9/3/2011 9:01 PM, Jon TURNEY wrote: > As discussed in the thread [2] various scenarios, e.g. AOT windows, > native windows interleaved with X windows in the native Z order, Windows > with focus-follows-mouse enabled via TweakUI all need testing after > trying to fix this, to ensure you haven't regressed them. > > [2] http://sourceware.org/ml/cygwin-xfree/2004-03/msg00540.html I'm not sure if I'm correctly reproducing the above usage scenario "always on top", but I did the following under Windows 7 and XP: 1) downloaded and installed http://www.abstractpath.com/powermenu/ 2) launched a xclock or a native Windows program (e.g. Internet Explorer) and select "Always on top" with right mouse click on the window's titel bar 3) programmatically launched and raised other x top level windows 4) Everything works: the checked windows stay top level, the programmatically raised windows became top level amongst all other "non always top level" windows and get keyboard focus and activated window frame. I was also able to minimize and restore the "always on top window" without any problems. Moreover the "redraw windows while moving and sizing" hack http://www.cygwin.com/ml/cygwin-xfree/2011-08/msg00049.html does also work with the "always on top" feature enabled for the foreground and background window. Also mixtures of cygwin x server windows with native Windows applications all with "always on top" feature enabled are working. What is not working: Clicking on "minimize to tray" on a cygwin x server window that has also the "always on top feature": this causes the window frame to vanish, but the window content is still redrawn by the xserver on the underlaying x11 window. This is difficult to describe, but this does also not work with the official unpatched cygwin x server 1.10.3-1. This "minimize-to-tray" effect for "always on top windows" is also described here: http://sourceware.org/ml/cygwin-xfree/2004-03/msg00540.html So according to my tests the patch does not introduce new misbehaviour regarding powermenu's "always on top" window feature. I could provide a patched binary XWin.exe, if someone wants to do more testing... Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: XRaiseWindow for activating windows in multiwindow mode
some additions to my last mail: On 04/09/11 10:52, Oliver Schmidt wrote: > code and is also necessary for the patch. I think that the recursice > behaviour occurs because changes on the top level windows with native > Windows-API-Calls are leading to native Windows messages that again are > fed into the x server and are leading to the funcion > winRestackWindowMultiWindow. But this is only a theory, After looking again at the code, I must correct my above statements: now I think, that it's not the native Windows function SetForegroundWindow that is calling the recursive behaviour. It's still the already existing code in the function winReorderWindowsMultiWindow that is causing recursive behaviour: in this existing code the function ConfigureWindow is invoked (this is not a native Windows function, it seems to be some x server function). So the invocation of this function is triggering the x server to invoke winRestackWindowMultiWindow recursively. But these are still theories. At least the recursive behaviour is not introduced by the patch, it was already there in the existing coding ;-) Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: XRaiseWindow for activating windows in multiwindow mode
Hi Jon, On 03/09/11 21:01, Jon TURNEY wrote: > There definitely are some problems in this area, but I'm not sure this is the > 'correct' fix, though. yes, it's some kind of workaround, but it works and is very useful for may daily work. At least the patch is very defensive, it just raises top level windows that should be on top over all other top level windows (i.e. have no previous sibling). Some programs become unusable if programmatically raised windows are not raised. Of course it would be better if the cygwin multiwindow mode would react on window manager messages, i.e. atom "_NET_ACTIVE_WINDOW" for raising windows. > The code as it stands is the product of some ... erm ... historical > compromises. I tried to left it mostly at it is, but yes, one can see that the coding at this point is a little bit "historic", especially the #if 1...#else block later on in the function winRestackWindowMultiWindow > this out. The code which perhaps would do this is in the disabled branch of > the #if/#else/#endif in winRestackWindowMultiWindow() yes, I had the same thoughts about it, but I didn't get it to work with this uncommented code. At least this uncommented code does not invoke SetForegroundWindow, so I doubt that it would raise windows under all conditions. > The relevant thread seems to be [2] and the relevant change seems to be [3], > but I can't reconstruct the reasoning behind it. > > As discussed in the thread [2] various scenarios, e.g. AOT windows, native > windows interleaved with X windows in the native Z order, Windows with > focus-follows-mouse enabled via TweakUI all need testing after trying to fix > this, to ensure you haven't regressed them. yes, is there any one here on this thread that uses these features and can confirm that they are still working with the patch? > I'd like this patch more if you said why recursive calls can occur, > and why they must be avoided. This was not my idea: it's just copied code from the function winReorderWindowsMultiWindow, so the reasons for avoiding the recursive behaviour are the same reasons that apply to existing code. The patched function winRestackWindowMultiWindow invokes the function winReorderWindowsMultiWindow in the #if 1 code block. So my idea was to move this lock a little bit higher, because with this patch critical work is done in the invoking fucunction winRestackWindowMultiWindow now. The recursive behaviour did occur in my testing, so this condition testing for avoiding recursive behaviour was necessary in the existing code and is also necessary for the patch. I think that the recursice behaviour occurs because changes on the top level windows with native Windows-API-Calls are leading to native Windows messages that again are fed into the x server and are leading to the funcion winRestackWindowMultiWindow. But this is only a theory, it is very difficult to find theses things out under cygwin, because stack traces via function "backtrace" from and "addr2line" are unfortunately not possible with cygwin :-( At least I'm happy now with my patched cygwin x server and I'm using it every day now ;-) Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: considering modifier keys after gaining focus
Hi Corinna, On 8/21/2011 10:43 AM, Corinna Vinschen wrote: >> However one problem is unsolved: if the key combination for opening >> window B (in the above example) is an AltGr key combination, the >> GetAsyncKeyState will also report, that the Ctrl key is pressed, >> which is not true, since this is the well known Windows fake Ctrl_L > > So, shouldn't something along these lines do the trick: > if (ctrl && altlang) > ctrl = FALSE; thanks! I tried your suggestion and now it is nearly perfect ;-) Only remaining drawback is now, that Ctrl+AltGr key kombinations still don't work when invoking/raising top level windows, but everything else is now working flawless: Ctrl, Shift+Ctrl, Alt, AltGr, Shift+Alt, Shift+AltGr etc. ;-) I think one has to live with the restriction that Ctrl+AltrGr doesn't work under Windows (BTW it works under Linux xserver, wheres Alt+AltGr works neither under Linux nor Windows). Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
redraw windows while resizing/moving windows in multiwindow mode
Hi, the following patch is a quick & dirty hack to enable redrawing of windows while the user moves or resizes the window. This patch should be seen as experimental proof that this can be done with only small changes in the source code. The main problem with window resizing/moving under Windows is, that in the function invocation stack dix/Dispatch -> os/WaitForSomething -> WakeupHandler -> hw/xwin/winWakeupHandler -> Windows/DispatchMessage -> hw/xwin/winTopLevelWindowProc the Windows function DispatchMessage does not return while the user resizes/moves a window. This function only returns after the user releases the mouse button. However the dix/Dispatch functions must be run to allow the clients to process the queued redraw/resizing events. The enclosed hack simply moves the invocation of DispatchMessage in winWakeupHandler outside WaitForSomething into Dispatch and breaks up the Dispatch function into a loop and inner dispatch handling that can be called from the winTopLevelWindowProc while WM_SIZE/WM_MOVE events are processed. This could further be improved by setting a windows timer while resizing moving to process clients messages even if the mouse is not moved while resizing (and therefore WM_SIZE/WM_MOVE events are not send). What do you think about this idea? One problem here is, that the dix package is also affected. Of course some work must be done to cleanly integrate this into the existing dix/hw architecture. Best regards, Oliver diff --git a/cygwin/dix/dispatch.c b/cygwin/dix/dispatch.c index 44f8087..18e9697 100644 --- a/cygwin/dix/dispatch.c +++ b/cygwin/dix/dispatch.c @@ -343,33 +343,27 @@ DisableLimitedSchedulingLatency(void) #define MAJOROP ((xReq *)client->requestBuffer)->reqType -void -Dispatch(void) -{ -int*clientReady; /* array of request ready clients */ -intresult; -ClientPtr client; -intnready; -HWEventQueuePtr* icheck = checkForInput; -long start_tick; +static int*clientReady; /* array of request ready clients */ +static int result; +static ClientPtr client; +static int nready; +static HWEventQueuePtr* icheck = checkForInput; +static longstart_tick; -nextFreeClientID = 1; -nClients = 0; - -clientReady = malloc(sizeof(int) * MaxClients); -if (!clientReady) - return; - -SmartScheduleSlice = SmartScheduleInterval; -while (!dispatchException) -{ +int DispatchOneStep(Bool handleWindowMessage) +{ +int rslt = 0; + if (*icheck[0] != *icheck[1]) { ProcessInputEvents(); FlushIfCriticalOutputPending(); } - nready = WaitForSomething(clientReady); + rslt = nready; + +if (handleWindowMessage) +handleNextWindowMessage(); if (nready && !SmartScheduleDisable) { @@ -460,6 +454,24 @@ Dispatch(void) client->smart_stop_tick = SmartScheduleTime; } dispatchException &= ~DE_PRIORITYCHANGE; + +return rslt; +} + +void +Dispatch(void) +{ +nextFreeClientID = 1; +nClients = 0; + +clientReady = malloc(sizeof(int) * MaxClients); +if (!clientReady) + return; + +SmartScheduleSlice = SmartScheduleInterval; +while (!dispatchException) +{ +DispatchOneStep(TRUE); } if (ddxHooks.ddxBeforeReset) diff --git a/cygwin/hw/xwin/winmultiwindowwndproc.c b/cygwin/hw/xwin/winmultiwindowwndproc.c index bd84c05..265fdcc 100644 --- a/cygwin/hw/xwin/winmultiwindowwndproc.c +++ b/cygwin/hw/xwin/winmultiwindowwndproc.c @@ -321,6 +321,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, static Bool s_fTracking = FALSE; Bool needRestack = FALSE; LRESULT ret; + static Bool hasEnteredSizeMove = FALSE; #if CYGDEBUG winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); @@ -871,7 +872,15 @@ winTopLevelWindowProc (HWND hwnd, UINT message, case WM_MOVE: /* Adjust the X Window to the moved Windows window */ - winAdjustXWindow (pWin, hwnd); + if (!hasEnteredSizeMove) +{ + winAdjustXWindow (pWin, hwnd); +} + else +{ + winAdjustXWindow (pWin, hwnd); + while (DispatchOneStep(FALSE) > 0) {} +} return 0; case WM_SHOWWINDOW: @@ -1012,6 +1021,16 @@ winTopLevelWindowProc (HWND hwnd, UINT message, */ break; +case WM_ENTERSIZEMOVE: + hasEnteredSizeMove = TRUE; + return 0; + +case WM_EXITSIZEMOVE: + /* Adjust the X Window to the moved Windows window */ + hasEnteredSizeMove = FALSE; + winAdjustXWindow (pWin, hwnd); + return 0; + case WM_SIZE: /* see dix/window.c */ #if CYGWINDOWING_DEBUG @@ -1036,9 +1055,17 @@ winTopLevelWindowProc (HWND hwnd, UINT message, (int)(GetTickCount ()));
minimize redraw events after resizing/moving windows in multiwindow mode
Hi, in multiwindow mode the modal moving/resizing of windows causes a lot of redraw events send to the X clients after the userse releases the mouse button. During the moving/resizing client windows are not redrawn as long as the mouse button is pressed. But all redraw/resizing events are queued and executed step after step after moving/resizing ends. Some clients collect and combine multiple redraw or resizing events, other clients (e.g. xterm) simply execute each redraw or sizing event. The enclosed patch minimizes the events for clients to only one event after the user releases the mouse button to end the moving/resizing. This improves the user experience and reduces strange screen flickerings especially on slow platforms. The enclosed patch modifies winmultiwindowwndproc.c such that the windows events WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE are considered that are send from windows if the modal window resizing/moving begins or ends. Only after WM_EXITSIZEMOVE the redraw/resizing is executed. The patch is against the sources of xserver-cygwin version 1.10.3-1. Best regards, Oliver diff --git a/cygwin/hw/xwin/winmultiwindowwndproc.c b/cygwin/hw/xwin/winmultiwindowwndproc.c index bd84c05..5f536d0 100644 --- a/cygwin/hw/xwin/winmultiwindowwndproc.c +++ b/cygwin/hw/xwin/winmultiwindowwndproc.c @@ -321,6 +321,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, static Bool s_fTracking = FALSE; Bool needRestack = FALSE; LRESULT ret; + static Bool hasEnteredSizeMove = FALSE; #if CYGDEBUG winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); @@ -871,7 +872,8 @@ winTopLevelWindowProc (HWND hwnd, UINT message, case WM_MOVE: /* Adjust the X Window to the moved Windows window */ - winAdjustXWindow (pWin, hwnd); + if (!hasEnteredSizeMove) winAdjustXWindow (pWin, hwnd); + /* else: Wait for WM_EXITSIZEMOVE */ return 0; case WM_SHOWWINDOW: @@ -1012,6 +1014,16 @@ winTopLevelWindowProc (HWND hwnd, UINT message, */ break; +case WM_ENTERSIZEMOVE: + hasEnteredSizeMove = TRUE; + return 0; + +case WM_EXITSIZEMOVE: + /* Adjust the X Window to the moved Windows window */ + hasEnteredSizeMove = FALSE; + winAdjustXWindow (pWin, hwnd); + return 0; + case WM_SIZE: /* see dix/window.c */ #if CYGWINDOWING_DEBUG @@ -1036,9 +1048,13 @@ winTopLevelWindowProc (HWND hwnd, UINT message, (int)(GetTickCount ())); } #endif - /* Adjust the X Window to the moved Windows window */ - winAdjustXWindow (pWin, hwnd); - if (wParam == SIZE_MINIMIZED) winReorderWindowsMultiWindow(); + if (!hasEnteredSizeMove) +{ + /* Adjust the X Window to the moved Windows window */ + winAdjustXWindow (pWin, hwnd); + if (wParam == SIZE_MINIMIZED) winReorderWindowsMultiWindow(); +} +/* else: wait for WM_EXITSIZEMOVE */ return 0; /* end of WM_SIZE handler */ case WM_STYLECHANGING: -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: (X)Emacs Window Manager commands
On 8/17/2011 3:07 PM, Gulliver.M.Smith wrote: In emacs, you can use the file menu to create a new frame (window). (raise-frame f) (iconify-frame f) (decionify-frame f) (make-frame-visible f) at least "raise-frame" works with my simple patch for raising top level windows, see http://www.cygwin.com/ml/cygwin-xfree/2011-08/msg00034.html >> EWMH and ICCCM standards Of course it would be nicer to have the window manager standards to be fulfilled by the cygwin multiwindow mode, which would be reacting on client messages with atom "_NET_ACTIVE_WINDOW" for raising windows. By the way: Unfortunately the xemaces from current cygwin distribution (21.4.22-1) seems broken and is not able to create other windows (e.g. when using the menu entry File/Open In New Frame. (This has nothing to do with the cygwin xserver, the cygwin xemacs does also not work with other xservers). However I was able to reproduce your steps using a linux xemacs with the cygwin xserver Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
considering modifier keys after gaining focus
Hi, I had the problem, that the state of the modifier keys was lost when a window is created (or raised). Example: in window A Ctrl + some key opens a window B, then in window B Ctrl + some other key triggers the next action. However after the opening of window B the Ctrl key has to be released and pressed again. If the user keeps the Ctrl key holding when the window B is opened, the next key press X will be interpreted as X and not as Ctrl+X. I send a patch to fix this problem with this email: I just extended the function winRestoreModeKeyStates in winkeybd.c to consider not only the mode switch key but also the modifiers Ctrl, Shift, Alt/AltGr by using the Windows function GetAsyncKeyState. This patch works fine for me. However one problem is unsolved: if the key combination for opening window B (in the above example) is an AltGr key combination, the GetAsyncKeyState will also report, that the Ctrl key is pressed, which is not true, since this is the well known Windows fake Ctrl_L :-( Any suggestions how to solve this? Best regards, Oliver diff --git a/cygwin/hw/xwin/winkeybd.c b/cygwin/hw/xwin/winkeybd.c index 9e5a9b0..e807fc5 100644 --- a/cygwin/hw/xwin/winkeybd.c +++ b/cygwin/hw/xwin/winkeybd.c @@ -255,6 +255,7 @@ void winRestoreModeKeyStates (void) { DWORDdwKeyState; + BOOL modifierPressed; BOOL processEvents = TRUE; unsigned short internalKeyStates; @@ -282,6 +283,34 @@ winRestoreModeKeyStates (void) * have a logical XOR operator, so we use a macro instead. */ + modifierPressed = (GetAsyncKeyState (VK_CONTROL) < 0); + if (WIN_XOR (internalKeyStates & ControlMask, modifierPressed)) +{ + if (modifierPressed) winSendKeyEvent (KEY_LCtrl, TRUE); + else winSendKeyEvent (KEY_LCtrl, FALSE); +} + + modifierPressed = (GetAsyncKeyState (VK_SHIFT) < 0); + if (WIN_XOR (internalKeyStates & ShiftMask, modifierPressed)) +{ + if (modifierPressed) winSendKeyEvent (KEY_ShiftL, TRUE); + else winSendKeyEvent (KEY_ShiftL, FALSE); +} + + modifierPressed = (GetAsyncKeyState (VK_LMENU) < 0); + if (WIN_XOR (internalKeyStates & Mod1Mask, modifierPressed)) +{ + if (modifierPressed) winSendKeyEvent (KEY_Alt, TRUE); + else winSendKeyEvent (KEY_Alt, FALSE); +} + + modifierPressed = (GetAsyncKeyState (VK_RMENU) < 0); + if (WIN_XOR (internalKeyStates & Mod5Mask, modifierPressed)) +{ + if (modifierPressed) winSendKeyEvent (KEY_AltLang, TRUE); + else winSendKeyEvent (KEY_AltLang, FALSE); +} + /* Has the key state changed? */ dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001; if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState)) -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: AltGr key mostly fires an additional CONTROL key
Hi Paul, On 8/15/2011 7:13 PM, Paul Maier wrote: the ftp://.exe.bz2 that you mention wasn't intended to contain any fix; it only produces additional debug statements. sorry, for pasting the wrong link. This is the one, that contains Jon's fix (works fine for me): ftp://cygwin.com/pub/cygwinx/XWin.20110803-git-a493c0465e56ce0b.exe.bz2 to be sure I downloaded and tested this version again and it still doesn't fix the AltGr problem reliably. I tested also on my older notebook which has Windows XP and only one core with the current official Cygwin release: no problems with AltGr at all. My newer notebook has Windows 7 and quadcore. So it seems that this is a timing problem or race condition that has something to do with newer Windows versions and/or multi core architecture. Best regards, Oliver -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/
Re: AltGr key mostly fires an additional CONTROL key
Hi, I also had problems with the AltGr key. These could reliably be reproduced by holding the AltGr for some seconds (causing Windows generating auto repeat events). Unfortunately the test version at ftp://cygwin.com/pub/cygwinx/XWin.20110801-git-2d9f9305cb559907.exe.bz2 doesn't fix this problem for me. I discovered that the mechanism in winkeybd.c function winIsFakeCtrl_L had a problem if PeekMessage cannot obtain the next Alt_R message because it is not there. I prepared a patch that remembers the last Ctrl_L event and reacts on a later following Alt_R. It was also necessary to alter the order in winWindowProc in winwndproc.c: the invocation of winIsFakeCtrl_L had to be done before discarding auto-repeated key presses. The attached patch is against the sources of xserver-cygwin-1.10.3-1. Best regards, Oliver diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c index e807fc5..460c9d6 100644 --- a/hw/xwin/winkeybd.c +++ b/hw/xwin/winkeybd.c @@ -356,6 +356,12 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) MSG msgNext; LONG lTime; Bool fReturn; + + static Bool hasLastControlL = FALSE; + static UINT lastMessage; + static WPARAM lastWparam; + static LPARAM lastLparam; + static LONG lastTime; /* * Fake Ctrl_L presses will be followed by an Alt_R keypress @@ -389,9 +395,22 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) WM_KEYDOWN, WM_SYSKEYDOWN, PM_NOREMOVE); } - if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN) + if (fReturn && msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN) fReturn = 0; + if (!fReturn) +{ + hasLastControlL = TRUE; + lastMessage = message; + lastWparam = wParam; + lastLparam = lParam; + lastTime= lTime; +} + else +{ + hasLastControlL = FALSE; +} + /* Is next press an Alt_R with the same timestamp? */ if (fReturn && msgNext.wParam == VK_MENU && msgNext.time == lTime @@ -406,11 +425,33 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) } } + /* + * Check for Alt_R keypress, that was not ready when the + * last Ctrl_L appeared. + */ + else if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN) + && wParam == VK_MENU + && (HIWORD (lParam) & KF_EXTENDED)) +{ + if (hasLastControlL) +{ + lTime = GetMessageTime (); + + if ((lastMessage == WM_KEYDOWN || lastMessage == WM_SYSKEYDOWN) + && lastTime == lTime) +{ +/* take back the fake ctrl_L key */ +winSendKeyEvent (KEY_LCtrl, FALSE); +} + hasLastControlL = FALSE; +} +} + /* * Fake Ctrl_L releases will be followed by an Alt_R release * with the same timestamp as the Ctrl_L release. */ - if ((message == WM_KEYUP || message == WM_SYSKEYUP) + else if ((message == WM_KEYUP || message == WM_SYSKEYUP) && wParam == VK_CONTROL && (HIWORD (lParam) & KF_EXTENDED) == 0) { @@ -439,9 +480,11 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) PM_NOREMOVE); } - if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP) + if (fReturn && msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP) fReturn = 0; +hasLastControlL = FALSE; + /* Is next press an Alt_R with the same timestamp? */ if (fReturn && (msgNext.message == WM_KEYUP @@ -458,6 +501,10 @@ winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) return TRUE; } } + else +{ + hasLastControlL = FALSE; +} /* Not a fake control left press/release */ return FALSE; diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index 316cf08..7de5a5d 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -1060,6 +1060,10 @@ winWindowProc (HWND hwnd, UINT message, if ((wParam == VK_LWIN || wParam == VK_RWIN) && !g_fKeyboardHookLL) break; + /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */ + if (winIsFakeCtrl_L (message, wParam, lParam)) + return 0; + /* * Discard presses generated from Windows auto-repeat */ @@ -1080,10 +1084,6 @@ winWindowProc (HWND hwnd, UINT message, } } - /* Discard fake Ctrl_L presses that precede AltGR on non-US keyboards */ - if (winIsFakeCtrl_L (message, wParam, lParam)) - return 0; - /* Translate Windows key code to X scan code */ winTranslateKey (wParam, lParam, &iScanCode); -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/pro
XRaiseWindow for activating windows in multiwindow mode
Hi, as reported in http://www.cygwin.com/ml/cygwin-xfree/2005-06/msg00072.html windows are not raised from the Cygwin X Server in multiwindow mode, if a program wants to programmatically activate a window. I played around and figured out that the problem can be solved by invoking the windows function SetForegroundWindow if a top level window is to be restacked and has no previous sibling. I enclose the patch in this email. It works fine for me, but I'm not sure if it has any side effects for other configurations or usage patterns. It would be nice if this feature could be integrated into future versions of the Cygwin X Server. Best regards, Oliver diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index 956a9a5..22390b3 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -465,6 +465,7 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) HWND hInsertAfter; HWND hWnd = NULL; #endif + static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */ ScreenPtrpScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); @@ -472,10 +473,27 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) winTrace ("winRestackMultiWindow - %08x\n", pWin); #endif + if (fRestacking) +{ + /* It is a recusive call so immediately exit */ +#if CYGWINDOWING_DEBUG + ErrorF ("winRestackWindowMultiWindow - " + "exit because fRestacking == TRUE\n"); +#endif + return; +} + fRestacking = TRUE; + WIN_UNWRAP(RestackWindow); if (pScreen->RestackWindow) (*pScreen->RestackWindow)(pWin, pOldNextSib); WIN_WRAP(RestackWindow, winRestackWindowMultiWindow); + + if (isToplevelWindow(pWin) && pWin->prevSib == NULL) +{ + winWindowPriv(pWin); + SetForegroundWindow(pWinPriv->hWnd); +} #if 1 /* @@ -538,6 +556,8 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) 0, 0, uFlags); #endif + + fRestacking = FALSE; } static void diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c index 956a9a5..22390b3 100644 --- a/hw/xwin/winmultiwindowwindow.c +++ b/hw/xwin/winmultiwindowwindow.c @@ -465,6 +465,7 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) HWND hInsertAfter; HWND hWnd = NULL; #endif + static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */ ScreenPtrpScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); @@ -472,10 +473,27 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) winTrace ("winRestackMultiWindow - %08x\n", pWin); #endif + if (fRestacking) +{ + /* It is a recusive call so immediately exit */ +#if CYGWINDOWING_DEBUG + ErrorF ("winRestackWindowMultiWindow - " + "exit because fRestacking == TRUE\n"); +#endif + return; +} + fRestacking = TRUE; + WIN_UNWRAP(RestackWindow); if (pScreen->RestackWindow) (*pScreen->RestackWindow)(pWin, pOldNextSib); WIN_WRAP(RestackWindow, winRestackWindowMultiWindow); + + if (isToplevelWindow(pWin) && pWin->prevSib == NULL) +{ + winWindowPriv(pWin); + SetForegroundWindow(pWinPriv->hWnd); +} #if 1 /* @@ -538,6 +556,8 @@ winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) 0, 0, uFlags); #endif + + fRestacking = FALSE; } static void -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://x.cygwin.com/docs/ FAQ: http://x.cygwin.com/docs/faq/