/********************************************************************** * EVENT_FocusIn */ static void EVENT_FocusIn( HWND hwnd, XEvent *xev ) { XFocusChangeEvent *event = &xev->xfocus; XIC xic; if (!hwnd) return; TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] ); if (event->detail == NotifyPointer) return; if ((xic = X11DRV_get_ic( hwnd ))) { wine_tsx11_lock(); XSetICFocus( xic ); wine_tsx11_unlock(); } if (use_take_focus) return; /* ignore FocusIn if we are using take focus */ if (!can_activate_window(hwnd)) { HWND hwnd = GetFocus(); if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT ); if (!hwnd) hwnd = GetActiveWindow(); if (!hwnd) hwnd = x11drv_thread_data()->last_focus; if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, CurrentTime ); } else SetForegroundWindow( hwnd ); }
/******************************************************************* * WINPOS_ActivateOtherWindow * * Activates window other than pWnd. */ void WINAPI WinPosActivateOtherWindow(HWND hwnd) { HWND hwndTo, fg; if ((GetWindowLongPtrW( hwnd, GWL_STYLE ) & WS_POPUP) && (hwndTo = GetWindow( hwnd, GW_OWNER ))) { hwndTo = GetAncestor( hwndTo, GA_ROOT ); if (can_activate_window( hwndTo )) goto done; } hwndTo = hwnd; for (;;) { if (!(hwndTo = GetWindow( hwndTo, GW_HWNDNEXT ))) break; if (can_activate_window( hwndTo )) break; } done: fg = GetForegroundWindow(); TRACE("win = %p fg = %p\n", hwndTo, fg); if (!fg || (hwnd == fg)) { if (SetForegroundWindow( hwndTo )) return; } if (!SetActiveWindow( hwndTo )) SetActiveWindow(0); }
/********************************************************************** * handle_wm_protocols */ static void handle_wm_protocols( HWND hwnd, XClientMessageEvent *event ) { Atom protocol = (Atom)event->data.l[0]; if (!protocol) return; if (protocol == x11drv_atom(WM_DELETE_WINDOW)) { /* Ignore the delete window request if the window has been disabled * and we are in managed mode. This is to disallow applications from * being closed by the window manager while in a modal state. */ if (IsWindowEnabled(hwnd)) { HMENU hSysMenu; if (GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) return; hSysMenu = GetSystemMenu(hwnd, FALSE); if (hSysMenu) { UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND); if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED))) return; } PostMessageW( hwnd, WM_X11DRV_DELETE_WINDOW, 0, 0 ); } } else if (protocol == x11drv_atom(WM_TAKE_FOCUS)) { Time event_time = (Time)event->data.l[1]; HWND last_focus = x11drv_thread_data()->last_focus; TRACE( "got take focus msg for %p, enabled=%d, visible=%d (style %08lx), focus=%p, active=%p, fg=%p, last=%p\n", hwnd, IsWindowEnabled(hwnd), IsWindowVisible(hwnd), GetWindowLongW(hwnd, GWL_STYLE), GetFocus(), GetActiveWindow(), GetForegroundWindow(), last_focus ); if (can_activate_window(hwnd)) { /* simulate a mouse click on the caption to find out * whether the window wants to be activated */ LRESULT ma = SendMessageW( hwnd, WM_MOUSEACTIVATE, (WPARAM)GetAncestor( hwnd, GA_ROOT ), MAKELONG(HTCAPTION,WM_LBUTTONDOWN) ); if (ma != MA_NOACTIVATEANDEAT && ma != MA_NOACTIVATE) set_focus( hwnd, event_time ); else TRACE( "not setting focus to %p (%lx), ma=%ld\n", hwnd, event->window, ma ); } else { hwnd = GetFocus(); if (hwnd) hwnd = GetAncestor( hwnd, GA_ROOT ); if (!hwnd) hwnd = GetActiveWindow(); if (!hwnd) hwnd = last_focus; if (hwnd && can_activate_window(hwnd)) set_focus( hwnd, event_time ); } } else if (protocol == x11drv_atom(_NET_WM_PING)) { XClientMessageEvent xev; xev = *event; TRACE("NET_WM Ping\n"); wine_tsx11_lock(); xev.window = DefaultRootWindow(xev.display); XSendEvent(xev.display, xev.window, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xev); wine_tsx11_unlock(); /* this line is semi-stolen from gtk2 */ TRACE("NET_WM Pong\n"); } }