Impemented window activity support and remove/apply focus when window activity change.

This commit is contained in:
and3md 2017-08-11 22:21:17 +02:00
parent 6c5c5b0e0e
commit f18002d732
6 changed files with 112 additions and 12 deletions

View File

@ -37,6 +37,15 @@ class AndroidWindow : Window {
return null;
}
override protected void handleWindowActivityChange(bool isWindowActive) {
super.handleWindowActivityChange(isWindowActive);
}
override @property bool isActive() {
//todo:
return true;
}
protected dstring _caption;
/// returns window caption
override @property dstring windowCaption() {

View File

@ -118,6 +118,12 @@ interface OnWindowStateHandler {
bool onWindowStateChange(Window window, WindowState winState, Rect rect);
}
/// Window activate/deactivate signal listener
interface OnWindowActivityHandler {
/// signal listener - called when window activity is changed
bool onWindowActivityChange(Window window, bool isWindowActive);
}
/// protected event list
/// references to posted messages can be stored here at least to keep live reference and avoid GC
/// as well, on some platforms it's easy to send id to message queue, but not pointer
@ -907,6 +913,7 @@ class Window : CustomEventTarget {
}
protected Widget _focusedWidget;
protected auto _focusStateToApply = State.Focused;
/// returns current focused widget
@property Widget focusedWidget() {
if (!isChild(_focusedWidget))
@ -922,6 +929,7 @@ class Window : CustomEventTarget {
auto targetState = State.Focused;
if(reason == FocusReason.TabFocus)
targetState = State.Focused | State.KeyboardFocused;
_focusStateToApply = targetState;
if (oldFocus is newFocus)
return oldFocus;
if (oldFocus !is null) {
@ -943,6 +951,40 @@ class Window : CustomEventTarget {
}
return _focusedWidget;
}
protected Widget removeFocus() {
if (!isChild(_focusedWidget))
_focusedWidget = null;
if (_focusedWidget) {
_focusedWidget.resetState(_focusStateToApply);
update();
}
return _focusedWidget;
}
protected Widget applyFocus() {
if (!isChild(_focusedWidget))
_focusedWidget = null;
if (_focusedWidget) {
_focusedWidget.setState(_focusStateToApply);
update();
}
return _focusedWidget;
}
abstract @property bool isActive();
/// window state change signal
Signal!OnWindowActivityHandler windowActivityChanged;
protected void handleWindowActivityChange(bool isWindowActive) {
if (isWindowActive)
applyFocus();
else
removeFocus();
if (windowActivityChanged.assigned)
windowActivityChanged(this, isWindowActive);
}
/// dispatch key event to widgets which have wantsKeyTracking == true
protected bool dispatchKeyEvent(Widget root, KeyEvent event) {

View File

@ -56,6 +56,16 @@ class ConsoleWindow : Window {
override @property Window parentWindow() {
return _parent;
}
override protected void handleWindowActivityChange(bool isWindowActive) {
super.handleWindowActivityChange(isWindowActive);
}
override @property bool isActive() {
// todo
return true;
}
protected bool _visible;
/// returns true if window is shown

View File

@ -455,15 +455,22 @@ class SDLWindow : Window {
else
handleWindowStateChange(newState, RECT_VALUE_IS_NOT_SET);
return res;
}
override @property Window parentWindow() {
return _parent;
}
override protected void handleWindowActivityChange(bool isWindowActive) {
super.handleWindowActivityChange(isWindowActive);
}
override @property bool isActive() {
uint flags = SDL_GetWindowFlags(_win);
return (flags & SDL_WINDOW_INPUT_FOCUS) == SDL_WINDOW_INPUT_FOCUS;
}
protected dstring _caption;
override @property dstring windowCaption() {
@ -1344,9 +1351,11 @@ class SDLPlatform : Platform {
debug(DebugSDL) Log.d("SDL_WINDOWEVENT_FOCUS_GAINED - ", w.windowCaption);
if (!_windowsMinimized)
w.restoreModalChilds();
w.handleWindowActivityChange(true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
debug(DebugSDL) Log.d("SDL_WINDOWEVENT_FOCUS_LOST - ", w.windowCaption);
w.handleWindowActivityChange(false);
break;
default:
break;

View File

@ -501,6 +501,14 @@ class Win32Window : Window {
return _w32parent;
}
override protected void handleWindowActivityChange(bool isWindowActive) {
super.handleWindowActivityChange(isWindowActive);
}
override @property bool isActive() {
return _hwnd == GetForegroundWindow();
}
override @property dstring windowCaption() {
return _caption;
}
@ -1087,7 +1095,7 @@ class Win32Platform : Platform {
for (uint i = 0; i + 1 < _windowList.length; i++) {
if (_windowList[i] is w) {
for (uint j = i + 1; j < _windowList.length; j++) {
if (_windowList[j].flags & WindowFlag.Modal && _windowList[j]._windowState != WindowState.hidden)
if (_windowList[j].flags & WindowFlag.Modal && _windowList[j].windowState != WindowState.hidden)
return true;
}
return false;
@ -1393,6 +1401,16 @@ LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
}
return 0;
case WM_ACTIVATE:
{
if (window) {
if (wParam == WA_INACTIVE)
window.handleWindowActivityChange(false);
else if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
window.handleWindowActivityChange(true);
}
}
return 0;
case CUSTOM_MESSAGE_ID:
if (window !is null) {
window.handlePostedEvent(cast(uint)lParam);

View File

@ -444,6 +444,10 @@ class X11Window : DWindow {
}
}
override protected void handleWindowStateChange(WindowState newState, Rect newWindowRect = RECT_VALUE_IS_NOT_SET) {
super.handleWindowStateChange(newState, newWindowRect);
}
protected final void changeWindowState(int action, Atom firstProperty, Atom secondProperty = None) nothrow
{
XEvent ev;
@ -561,6 +565,16 @@ class X11Window : DWindow {
return _parent;
}
private bool _isActive;
override protected void handleWindowActivityChange(bool isWindowActive) {
_isActive = isWindowActive;
super.handleWindowActivityChange(isWindowActive);
}
override @property bool isActive() {
return _isActive;
}
override @property dstring windowCaption() {
return _caption;
}
@ -618,10 +632,6 @@ class X11Window : DWindow {
_platform.closeWindow(this);
}
override protected void handleWindowStateChange(WindowState newState, Rect newWindowRect = RECT_VALUE_IS_NOT_SET) {
super.handleWindowStateChange(newState, newWindowRect);
}
ColorDrawBuf _drawbuf;
protected void drawUsingBitmap() {
if (_dx > 0 && _dy > 0) {
@ -1519,16 +1529,18 @@ class X11Platform : Platform {
case FocusIn:
Log.d("X11: FocusIn event");
X11Window w = findWindow(event.xfocus.window);
if (!w) {
if (w)
w.handleWindowActivityChange(true);
else
Log.e("Window not found");
}
break;
case FocusOut:
Log.d("X11: FocusOut event");
X11Window w = findWindow(event.xfocus.window);
if (!w) {
if (w)
w.handleWindowActivityChange(false);
else
Log.e("Window not found");
}
break;
case KeymapNotify:
Log.d("X11: KeymapNotify event");
@ -1667,7 +1679,7 @@ class X11Platform : Platform {
for (uint i = 0; i + 1 < _windowList.length; i++) {
if (_windowList[i] is w) {
for (uint j = i + 1; j < _windowList.length; j++) {
if (_windowList[j].flags & WindowFlag.Modal && _windowList[j]._windowState != WindowState.hidden)
if (_windowList[j].flags & WindowFlag.Modal && _windowList[j].windowState != WindowState.hidden)
return true;
}
return false;