diff options
Diffstat (limited to 'src/newt/native/X11Display.c')
-rw-r--r-- | src/newt/native/X11Display.c | 293 |
1 files changed, 248 insertions, 45 deletions
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c index 7ac6e8639..7c6741839 100644 --- a/src/newt/native/X11Display.c +++ b/src/newt/native/X11Display.c @@ -35,7 +35,7 @@ jclass X11NewtWindowClazz = NULL; jmethodID insetsChangedID = NULL; jmethodID visibleChangedID = NULL; -jmethodID sizePosMaxInsetsChangedID = NULL; +jmethodID insetsVisibleChangedID = NULL; static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/WindowDriver"; @@ -46,13 +46,17 @@ static jmethodID getCurrentThreadNameID = NULL; static jmethodID dumpStackID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID positionChangedID = NULL; -static jmethodID focusChangedID = NULL; +static jmethodID focusVisibleChangedID = NULL; static jmethodID reparentNotifyID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowRepaintID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; static jmethodID sendMouseEventRequestFocusID = NULL; +static jmethodID visibleChangedWindowRepaintID = NULL; +static jmethodID visibleChangedSendMouseEventID = NULL; +static jmethodID sizePosMaxInsetsVisibleChangedID = NULL; +static jmethodID sendTouchScreenEventID = NULL; /** * Keycode @@ -244,22 +248,26 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 } } - // displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJJII)V"); // Variant using XKB - displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJII)V"); + // displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJJIII)V"); // Variant using XKB + displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJIII)V"); sendRRScreenChangeNotifyID = (*env)->GetMethodID(env, clazz, "sendRRScreenChangeNotify", "(J)V"); getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "getCurrentThreadName", "()Ljava/lang/String;"); dumpStackID = (*env)->GetStaticMethodID(env, X11NewtWindowClazz, "dumpStack", "()V"); insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V"); sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZIIZ)V"); positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V"); - focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V"); + focusVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusVisibleChanged", "(ZII)V"); visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V"); - sizePosMaxInsetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizePosMaxInsetsChanged", "(ZIIIIZZIIIIZ)V"); + insetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsVisibleChanged", "(ZIIIII)V"); + sizePosMaxInsetsVisibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizePosMaxInsetsVisibleChanged", "(ZIIIIIIIIIIIZ)V"); reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "(Z)Z"); windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V"); + visibleChangedWindowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedWindowRepaint", "(ZIIIII)V"); sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(SIIISF)V"); sendMouseEventRequestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEventRequestFocus", "(SIIISF)V"); + visibleChangedSendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChangedSendMouseEvent", "(ZISIIISF)V"); + sendTouchScreenEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendTouchScreenEvent", "(SII[I[I[I[FF)V"); sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(SISSCLjava/lang/String;)V"); if (displayCompletedID == NULL || @@ -269,19 +277,22 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_initIDs0 insetsChangedID == NULL || sizeChangedID == NULL || positionChangedID == NULL || - focusChangedID == NULL || + focusVisibleChangedID == NULL || visibleChangedID == NULL || - sizePosMaxInsetsChangedID == NULL || + insetsVisibleChangedID == NULL || + sizePosMaxInsetsVisibleChangedID == NULL || reparentNotifyID == NULL || windowDestroyNotifyID == NULL || windowRepaintID == NULL || + visibleChangedWindowRepaintID == NULL || sendMouseEventID == NULL || sendMouseEventRequestFocusID == NULL || + visibleChangedSendMouseEventID == NULL || + sendTouchScreenEventID == NULL || sendKeyEventID == NULL) { return JNI_FALSE; } - return JNI_TRUE; } @@ -320,10 +331,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_CompleteDisplay int randr_event_base, randr_error_base; XRRQueryExtension(dpy, &randr_event_base, &randr_error_base); + int xi_opcode = -1, event, error; + XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error); + DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy); (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom /*, kbdHandle*/, // XKB disabled for now - randr_event_base, randr_error_base); + randr_event_base, randr_error_base, xi_opcode); } /* @@ -353,14 +367,96 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DisplayRelease0 DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy); } +static int NewtWindows_updateVisibility(JNIEnv *env, Display *dpy, JavaWindow *jw, uint32_t netWMState, const char *dbgs) { + int visibleChange; + if( jw->isMapped && 0 != ( _MASK_NET_WM_STATE_HIDDEN & jw->supportedAtoms ) ) { + if( 0 != ( _MASK_NET_WM_STATE_HIDDEN & netWMState ) ) { + visibleChange = 0; + } else { + visibleChange = 1; + } + } else { + visibleChange = -1; + } + #ifdef VERBOSE_ON + XWindowAttributes xwa; + memset(&xwa, 0, sizeof(XWindowAttributes)); + XGetWindowAttributes(dpy, jw->window, &xwa); + + // map_state: IsUnmapped(0), IsUnviewable(1), IsViewable(2) + DBG_PRINT( "X11: event . %s call %p - isMapped %d, visibleChanged %d, map_state %d\n", + dbgs, (void*)jw->window, jw->isMapped, visibleChange, xwa.map_state); + #endif + return visibleChange; +} + +static void sendTouchScreenEvent(JNIEnv *env, JavaWindow *jw, + short eventType, // MouseEvent.EVENT_MOUSE_PRESSED, MouseEvent.EVENT_MOUSE_RELEASED, MouseEvent.EVENT_MOUSE_MOVED + int modifiers, // 0! + int actionId) // index of multiple-pointer arrays representing the pointer which triggered the event +{ + jint pointerNames[XI_TOUCHCOORD_COUNT]; + jint x[XI_TOUCHCOORD_COUNT]; + jint y[XI_TOUCHCOORD_COUNT]; + jfloat pressure[] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; + jint actionIdx = -1; + int i, cnt; + + for(i = 0, cnt = 0; i < XI_TOUCHCOORD_COUNT; i++) { + if( -1 != jw->xiTouchCoords[i].id ) { + x[cnt] = jw->xiTouchCoords[i].x; + y[cnt] = jw->xiTouchCoords[i].y; + pointerNames[cnt] = jw->xiTouchCoords[i].id; + if (jw->xiTouchCoords[i].id == actionId) { + actionIdx = cnt; + } + cnt++; + } + } + if( 0 > actionIdx ) { + NewtCommon_throwNewRuntimeException(env, "Internal Error: XI event (window %p) actionId %d not found in %d xiTouchCoords", + (void*)jw->window, actionId, cnt); + } + DBG_PRINT( "X11: XI event - sendTouchScreenEvent: Window %p, action-touchid[%d] %d of %d ptr: %d/%d\n", + (void*)jw->window, actionIdx, actionId, cnt, x[actionIdx], y[actionIdx]); + + jintArray jNames = (*env)->NewIntArray(env, cnt); + if (jNames == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (names) of size %d", cnt); + } + (*env)->SetIntArrayRegion(env, jNames, 0, cnt, pointerNames); + + jintArray jX = (*env)->NewIntArray(env, cnt); + if (jX == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (x) of size %d", cnt); + } + (*env)->SetIntArrayRegion(env, jX, 0, cnt, x); + + jintArray jY = (*env)->NewIntArray(env, cnt); + if (jY == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate int array (y) of size %d", cnt); + } + (*env)->SetIntArrayRegion(env, jY, 0, cnt, y); + + jfloatArray jPressure = (*env)->NewFloatArray(env, cnt); + if (jPressure == NULL) { + NewtCommon_throwNewRuntimeException(env, "Could not allocate float array (pressure) of size %d", cnt); + } + (*env)->SetFloatArrayRegion(env, jPressure, 0, cnt, pressure); + + (*env)->CallVoidMethod(env, jw->jwindow, sendTouchScreenEventID, + (jshort)eventType, (jint)modifiers, (jint)actionIdx, + jNames, jX, jY, jPressure, (jfloat)1.0f); +} + /* * Class: jogamp_newt_driver_x11_DisplayDriver * Method: DispatchMessages0 - * Signature: (JJJII)V + * Signature: (JJJIII)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessages0 (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom /*, jlong kbdHandle*/, - jint randr_event_base, jint randr_error_base) + jint randr_event_base, jint randr_error_base, jint xi_opcode) { Display * dpy = (Display *) (intptr_t) display; Atom wm_delete_atom = (Atom)windowDeleteAtom; @@ -411,17 +507,30 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage if( randr_event_base > 0 && RRScreenChangeNotify == ( evt.type - randr_event_base ) ) { DBG_PRINT( "X11: DispatchMessages dpy %p, Event RRScreenChangeNotify %p\n", (void*)dpy, (void*)&evt); (*env)->CallVoidMethod(env, obj, sendRRScreenChangeNotifyID, (jlong)(intptr_t)&evt); - continue; + continue; // next event } if( 0==evt.xany.window ) { DBG_PRINT( "X11: DispatchMessages dpy %p, Event %d - Window NULL, ignoring\n", (void*)dpy, (int)evt.type); - continue; + continue; // next event } - // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type); + // Valid registered XI Event w/ cookie data (incl. the event Window name)? + // Here: https://www.x.org/wiki/Development/Documentation/Multitouch/ + XGenericEventCookie *evtCookie = &evt.xcookie; // hacks: https://keithp.com/blogs/Cursor_tracking/ + int isXiEvent = GenericEvent == evtCookie->type && xi_opcode == evtCookie->extension && XGetEventData(dpy, evtCookie); + XIDeviceEvent *xiDevEv; + Window windowPointer; + if( !isXiEvent ) { + xiDevEv = NULL; + windowPointer = evt.xany.window; + DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)windowPointer, (int)evt.type); + } else { + xiDevEv = evtCookie->data; + windowPointer = xiDevEv->event; + } - jw = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom, + jw = getJavaWindowProperty(env, dpy, windowPointer, javaObjectAtom, #ifdef VERBOSE_ON True #else @@ -430,10 +539,62 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage ); if(NULL==jw) { - fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window); - continue; + fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)windowPointer); + continue; // next event } - + + if ( isXiEvent ) { + if( xiDevEv->deviceid != jw->xiTouchDeviceId) { + DBG_PRINT( "X11: XI event - dpy %p, win %p, Event %d: DeviceID not matching: Window %d, this %d\n", (void*)dpy, (void*)windowPointer, (int)evt.type, xiDevEv->deviceid, jw->xiTouchDeviceId); + } else { + int i; + switch (xiDevEv->evtype) { + case XI_TouchBegin: + for (i = 0; i < XI_TOUCHCOORD_COUNT; i++) { + if (jw->xiTouchCoords[i].id == -1) { + jw->xiTouchCoords[i].id = xiDevEv->detail % 32767; + jw->xiTouchCoords[i].x = xiDevEv->event_x; + jw->xiTouchCoords[i].y = xiDevEv->event_y; + break; + } + } + DBG_PRINT( "X11: XI event - XI_TouchBegin Window %p, devid %d, touchid[%d] %d @ %d/%d\n", (void*)windowPointer, xiDevEv->deviceid, + i, jw->xiTouchCoords[i].id, jw->xiTouchCoords[i].x, jw->xiTouchCoords[i].y); + sendTouchScreenEvent(env, jw, EVENT_MOUSE_PRESSED, 0, xiDevEv->detail % 32767); + break; + + case XI_TouchUpdate: + for (i = 0; i < XI_TOUCHCOORD_COUNT; i++) { + if (jw->xiTouchCoords[i].id == xiDevEv->detail % 32767) { + jw->xiTouchCoords[i].x = xiDevEv->event_x; + jw->xiTouchCoords[i].y = xiDevEv->event_y; + break; + } + } + DBG_PRINT( "X11: XI event - XI_TouchUpdate: Window %p, devid %d, touchid[%d] %d @ %d/%d\n", (void*)windowPointer, xiDevEv->deviceid, + i, jw->xiTouchCoords[i].id, jw->xiTouchCoords[i].x, jw->xiTouchCoords[i].y); + sendTouchScreenEvent(env, jw, EVENT_MOUSE_MOVED, 0, xiDevEv->detail % 32767); + break; + + case XI_TouchEnd: + for (i = 0; i < XI_TOUCHCOORD_COUNT; i++) { + if (jw->xiTouchCoords[i].id == xiDevEv->detail % 32767) { + break; + } + } + DBG_PRINT( "X11: XI event - XI_TouchEnd: Window %p, devid %d, touchid[%d] %d @ %d/%d\n", (void*)windowPointer, xiDevEv->deviceid, + i, jw->xiTouchCoords[i].id, jw->xiTouchCoords[i].x, jw->xiTouchCoords[i].y); + sendTouchScreenEvent(env, jw, EVENT_MOUSE_RELEASED, 0, xiDevEv->detail % 32767); + if ( i < XI_TOUCHCOORD_COUNT ) { + jw->xiTouchCoords[i].id = -1; + } + break; + } + } + XFreeEventData(dpy, evtCookie); + continue; // next event, skip evt.type handling below + } + switch(evt.type) { case KeyRelease: if (XEventsQueued(dpy, QueuedAfterReading)) { @@ -538,15 +699,23 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage break; case EnterNotify: DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y); - (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_ENTERED, - modifiers, - (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/); + { + uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw); + int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "EnterNotify"); + (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange, + (jshort) EVENT_MOUSE_ENTERED, modifiers, + (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/); + } break; case LeaveNotify: DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y); - (*env)->CallVoidMethod(env, jw->jwindow, sendMouseEventID, (jshort) EVENT_MOUSE_EXITED, - modifiers, - (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/); + { + uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw); + int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "LeaveNotify"); + (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedSendMouseEventID, JNI_FALSE, (jint)visibleChange, + (jshort) EVENT_MOUSE_EXITED, modifiers, + (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jshort) 0, 0.0f /*rotation*/); + } break; case MappingNotify: DBG_PRINT( "X11: event . MappingNotify call %p type %d\n", (void*)evt.xmapping.window, evt.xmapping.type); @@ -578,19 +747,25 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event); if ( evt.xconfigure.window == evt.xconfigure.event ) { // ignore child window change notification - // update insets + // insets: negative values are ignored int left=-1, right=-1, top=-1, bottom=-1; + uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw); + int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "ConfigureNotify"); NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom); - NewtWindows_updateMaximized(dpy, jw); - (*env)->CallVoidMethod(env, jw->jwindow, sizePosMaxInsetsChangedID, JNI_FALSE, + Bool maxChanged = NewtWindows_updateMaximized(dpy, jw, netWMState); + (*env)->CallVoidMethod(env, jw->jwindow, sizePosMaxInsetsVisibleChangedID, JNI_FALSE, (jint) evt.xconfigure.x, (jint) evt.xconfigure.y, (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, - (jboolean)jw->maxHorz, (jboolean)jw->maxVert, + (jint)(maxChanged ? ( jw->maxHorz ? 1 : 0 ) : -1), + (jint)(maxChanged ? ( jw->maxVert ? 1 : 0 ) : -1), (jint)left, (jint)right, (jint)top, (jint)bottom, + (jint)visibleChange, JNI_FALSE); } break; case ClientMessage: + DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X, sendEvent %d\n", + (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type, evt.xclient.send_event); if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom jboolean closed; DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X ..\n", @@ -604,48 +779,76 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_DisplayDriver_DispatchMessage break; case FocusIn: - DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window); - (*env)->CallVoidMethod(env, jw->jwindow, focusChangedID, JNI_FALSE, JNI_TRUE); + DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xfocus.window); + { + uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw); + int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusIn"); + (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)1, (jint)visibleChange); + } break; case FocusOut: - DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window); - (*env)->CallVoidMethod(env, jw->jwindow, focusChangedID, JNI_FALSE, JNI_FALSE); + DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xfocus.window); + { + uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw); + int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "FocusOut"); + (*env)->CallVoidMethod(env, jw->jwindow, focusVisibleChangedID, JNI_FALSE, (jint)0, (jint)visibleChange); + } break; + case VisibilityNotify: + DBG_PRINT( "X11: event . VisibilityNotify call %p\n", (void*)evt.xvisibility.window); + { + #if 0 + uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw); + int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "VisibilityNotify"); + if( 0 <= visibleChange ) { + (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, 0 < visibleChange ? JNI_TRUE : JNI_FALSE); + } + #endif + } + break; + + case Expose: DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window, evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count); - if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) { (*env)->CallVoidMethod(env, jw->jwindow, windowRepaintID, JNI_FALSE, evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height); + #if 0 + uint32_t netWMState = NewtWindows_getNET_WM_STATE(dpy, jw); + int visibleChange = NewtWindows_updateVisibility(env, dpy, jw, netWMState, "Expose"); + (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedWindowRepaintID, JNI_FALSE, (jint)visibleChange, + evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height); + #endif } break; case MapNotify: - DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n", - (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect, + DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, isMapped %d -> 1, override_redirect %d, child-event: %d\n", + (void*)evt.xmap.event, (void*)evt.xmap.window, jw->isMapped, (int)evt.xmap.override_redirect, evt.xmap.event!=evt.xmap.window); if( evt.xmap.event == evt.xmap.window ) { // ignore child window notification - { - // update insets - int left, right, top, bottom; - if( NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom) ) { - (*env)->CallVoidMethod(env, jw->jwindow, insetsChangedID, JNI_FALSE, left, right, top, bottom); - } + jw->isMapped = True; + // insets: negative values are ignored + int left=-1, right=-1, top=-1, bottom=-1; + if( NewtWindows_updateInsets(dpy, jw, &left, &right, &top, &bottom) ) { + (*env)->CallVoidMethod(env, jw->jwindow, insetsVisibleChangedID, JNI_FALSE, left, right, top, bottom, 1); + } else { + (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE); } - (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE); } break; case UnmapNotify: - DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n", - (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure, + DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, isMapped %d -> 0, from_configure %d, child-event: %d\n", + (void*)evt.xunmap.event, (void*)evt.xunmap.window, jw->isMapped, (int)evt.xunmap.from_configure, evt.xunmap.event!=evt.xunmap.window); if( evt.xunmap.event == evt.xunmap.window ) { // ignore child window notification + jw->isMapped = False; (*env)->CallVoidMethod(env, jw->jwindow, visibleChangedID, JNI_FALSE, JNI_FALSE); } break; |