@@ -64,6 +64,7 @@ internal unsafe partial class X11Window : IWindowImpl, IPopupImpl, IXI2Client
64
64
private RawEventGrouper ? _rawEventGrouper ;
65
65
private bool _useRenderWindow = false ;
66
66
private bool _usePositioningFlags = false ;
67
+ private X11FocusProxy _focusProxy ;
67
68
68
69
private enum XSyncState
69
70
{
@@ -157,6 +158,8 @@ public X11Window(AvaloniaX11Platform platform, IWindowImpl? popupParent, bool ov
157
158
_renderHandle = _handle ;
158
159
159
160
Handle = new PlatformHandle ( _handle , "XID" ) ;
161
+ _focusProxy = new X11FocusProxy ( platform , _handle , OnEvent ) ;
162
+ SetWmClass ( _focusProxy . _handle , "FocusProxy" ) ;
160
163
_realSize = new PixelSize ( defaultWidth , defaultHeight ) ;
161
164
platform . Windows [ _handle ] = OnEvent ;
162
165
XEventMask ignoredMask = XEventMask . SubstructureRedirectMask
@@ -176,7 +179,7 @@ public X11Window(AvaloniaX11Platform platform, IWindowImpl? popupParent, bool ov
176
179
XChangeProperty ( _x11 . Display , _handle , _x11 . Atoms . _NET_WM_WINDOW_TYPE , _x11 . Atoms . XA_ATOM ,
177
180
32 , PropertyMode . Replace , new [ ] { _x11 . Atoms . _NET_WM_WINDOW_TYPE_NORMAL } , 1 ) ;
178
181
179
- SetWmClass ( _platform . Options . WmClass ) ;
182
+ SetWmClass ( _handle , _platform . Options . WmClass ) ;
180
183
}
181
184
182
185
var surfaces = new List < object >
@@ -213,7 +216,7 @@ public X11Window(AvaloniaX11Platform platform, IWindowImpl? popupParent, bool ov
213
216
InitializeIme ( ) ;
214
217
215
218
XChangeProperty ( _x11 . Display , _handle , _x11 . Atoms . WM_PROTOCOLS , _x11 . Atoms . XA_ATOM , 32 ,
216
- PropertyMode . Replace , new [ ] { _x11 . Atoms . WM_DELETE_WINDOW , _x11 . Atoms . _NET_WM_SYNC_REQUEST } , 2 ) ;
219
+ PropertyMode . Replace , new [ ] { _x11 . Atoms . WM_DELETE_WINDOW , _x11 . Atoms . WM_TAKE_FOCUS , _x11 . Atoms . _NET_WM_SYNC_REQUEST } , 3 ) ;
217
220
218
221
if ( _x11 . HasXSync )
219
222
{
@@ -548,6 +551,11 @@ private void OnEvent(ref XEvent ev)
548
551
_xSyncValue . Hi = ev . ClientMessageEvent . ptr4 . ToInt32 ( ) ;
549
552
_xSyncState = XSyncState . WaitConfigure ;
550
553
}
554
+ else if ( ev . ClientMessageEvent . ptr1 == _x11 . Atoms . WM_TAKE_FOCUS )
555
+ {
556
+ IntPtr time = ev . ClientMessageEvent . ptr2 ;
557
+ XSetInputFocus ( _x11 . Display , _focusProxy . _handle , RevertTo . Parent , time ) ;
558
+ }
551
559
}
552
560
}
553
561
else if ( ev . type == XEventName . KeyPress || ev . type == XEventName . KeyRelease )
@@ -923,6 +931,8 @@ private void Cleanup(bool fromDestroyNotification)
923
931
{
924
932
_renderHandle = IntPtr . Zero ;
925
933
}
934
+
935
+ _focusProxy . Cleanup ( ) ;
926
936
}
927
937
928
938
private bool ActivateTransientChildIfNeeded ( )
@@ -1078,7 +1088,7 @@ public void Activate()
1078
1088
else
1079
1089
{
1080
1090
XRaiseWindow ( _x11 . Display , _handle ) ;
1081
- XSetInputFocus ( _x11 . Display , _handle , 0 , IntPtr . Zero ) ;
1091
+ XSetInputFocus ( _x11 . Display , _focusProxy . _handle , 0 , IntPtr . Zero ) ;
1082
1092
}
1083
1093
}
1084
1094
@@ -1170,7 +1180,7 @@ public void SetTitle(string? title)
1170
1180
}
1171
1181
}
1172
1182
1173
- public void SetWmClass ( string wmClass )
1183
+ public void SetWmClass ( IntPtr handle , string wmClass )
1174
1184
{
1175
1185
// See https://tronche.com/gui/x/icccm/sec-4.html#WM_CLASS
1176
1186
// We don't actually parse the application's command line, so we only use RESOURCE_NAME and argv[0]
@@ -1186,7 +1196,7 @@ public void SetWmClass(string wmClass)
1186
1196
{
1187
1197
hint ->res_name = pAppId ;
1188
1198
hint ->res_class = pWmClass ;
1189
- XSetClassHint ( _x11 . Display , _handle , hint ) ;
1199
+ XSetClassHint ( _x11 . Display , handle , hint ) ;
1190
1200
}
1191
1201
1192
1202
XFree ( hint ) ;
0 commit comments