Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_window.c')
-rw-r--r--source/blender/windowmanager/intern/wm_window.c175
1 files changed, 105 insertions, 70 deletions
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index a1ebe1fc76f..661db1b62e7 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -155,28 +155,30 @@ static void wm_window_check_size(rcti *rect)
static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win)
{
- if (win->ghostwin) {
- /* Prevents non-drawable state of main windows (bugs T22967,
- * T25071 and possibly T22477 too). Always clear it even if
- * this window was not the drawable one, because we mess with
- * drawing context to discard the GW context. */
- wm_window_clear_drawable(wm);
+ if (UNLIKELY(!win->ghostwin)) {
+ return;
+ }
- if (win == wm->winactive) {
- wm->winactive = NULL;
- }
+ /* Prevents non-drawable state of main windows (bugs T22967,
+ * T25071 and possibly T22477 too). Always clear it even if
+ * this window was not the drawable one, because we mess with
+ * drawing context to discard the GW context. */
+ wm_window_clear_drawable(wm);
- /* We need this window's opengl context active to discard it. */
- GHOST_ActivateWindowDrawingContext(win->ghostwin);
- GPU_context_active_set(win->gpuctx);
+ if (win == wm->winactive) {
+ wm->winactive = NULL;
+ }
+
+ /* We need this window's opengl context active to discard it. */
+ GHOST_ActivateWindowDrawingContext(win->ghostwin);
+ GPU_context_active_set(win->gpuctx);
- /* Delete local GPU context. */
- GPU_context_discard(win->gpuctx);
+ /* Delete local GPU context. */
+ GPU_context_discard(win->gpuctx);
- GHOST_DisposeWindow(g_system, win->ghostwin);
- win->ghostwin = NULL;
- win->gpuctx = NULL;
- }
+ GHOST_DisposeWindow(g_system, win->ghostwin);
+ win->ghostwin = NULL;
+ win->gpuctx = NULL;
}
void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
@@ -968,8 +970,8 @@ typedef enum {
OS = 'C',
} modifierKeyType;
-/* check if specified modifier key type is pressed */
-static int query_qual(modifierKeyType qual)
+/** Check if specified modifier key type is pressed. */
+static bool query_qual(modifierKeyType qual)
{
GHOST_TModifierKey left, right;
switch (qual) {
@@ -1113,14 +1115,22 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
}
wmWindow *win = GHOST_GetWindowUserData(ghostwin);
+ /* Win23/GHOST modifier bug, see T40317 */
+#ifndef WIN32
+//# define USE_WIN_ACTIVATE
+#endif
+
switch (type) {
case GHOST_kEventWindowDeactivate:
wm_event_add_ghostevent(wm, win, type, data);
win->active = 0; /* XXX */
- /* clear modifiers for inactive windows */
+ /* When window activation is enabled, these modifiers are set with window activation.
+ * Otherwise leave them set so re-activation doesn't loose keys which are held. */
+#ifdef USE_WIN_ACTIVATE
win->eventstate->modifier = 0;
win->eventstate->keymodifier = 0;
+#endif
break;
case GHOST_kEventWindowActivate: {
@@ -1128,11 +1138,6 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
(query_qual(CONTROL) ? KM_CTRL : 0) |
(query_qual(ALT) ? KM_ALT : 0) | (query_qual(OS) ? KM_OSKEY : 0));
- /* Win23/GHOST modifier bug, see T40317 */
-#ifndef WIN32
-//# define USE_WIN_ACTIVATE
-#endif
-
/* No context change! C->wm->windrawable is drawable, or for area queues. */
wm->winactive = win;
@@ -1367,6 +1372,10 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt
event.xy[0] = ddd->x;
event.xy[1] = ddd->y;
+ /* The values from #wm_window_update_eventstate may not match (under WAYLAND they don't)
+ * Write this into the event state. */
+ copy_v2_v2_int(win->eventstate->xy, event.xy);
+
event.flag = 0;
/* No context change! C->wm->windrawable is drawable, or for area queues. */
@@ -1551,36 +1560,55 @@ void wm_window_process_events(const bContext *C)
void wm_ghost_init(bContext *C)
{
- if (!g_system) {
- GHOST_EventConsumerHandle consumer;
+ if (g_system) {
+ return;
+ }
- if (C != NULL) {
- consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
- }
+ BLI_assert(C != NULL);
+ BLI_assert_msg(!G.background, "Use wm_ghost_init_background instead");
- GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace);
+ GHOST_EventConsumerHandle consumer;
- g_system = GHOST_CreateSystem();
+ consumer = GHOST_CreateEventConsumer(ghost_event_proc, C);
- GHOST_Debug debug = {0};
- if (G.debug & G_DEBUG_GHOST) {
- debug.flags |= GHOST_kDebugDefault;
- }
- if (G.debug & G_DEBUG_WINTAB) {
- debug.flags |= GHOST_kDebugWintab;
- }
- GHOST_SystemInitDebug(g_system, debug);
+ GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace);
- if (C != NULL) {
- GHOST_AddEventConsumer(g_system, consumer);
- }
+ g_system = GHOST_CreateSystem();
- if (wm_init_state.native_pixels) {
- GHOST_UseNativePixels();
- }
+ GHOST_Debug debug = {0};
+ if (G.debug & G_DEBUG_GHOST) {
+ debug.flags |= GHOST_kDebugDefault;
+ }
+ if (G.debug & G_DEBUG_WINTAB) {
+ debug.flags |= GHOST_kDebugWintab;
+ }
+ GHOST_SystemInitDebug(g_system, debug);
+
+ GHOST_AddEventConsumer(g_system, consumer);
+
+ if (wm_init_state.native_pixels) {
+ GHOST_UseNativePixels();
+ }
+
+ GHOST_UseWindowFocus(wm_init_state.window_focus);
+}
+
+/* TODO move this to wm_init_exit.c. */
+void wm_ghost_init_background(void)
+{
+ if (g_system) {
+ return;
+ }
+
+ GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace);
- GHOST_UseWindowFocus(wm_init_state.window_focus);
+ g_system = GHOST_CreateSystemBackground();
+
+ GHOST_Debug debug = {0};
+ if (G.debug & G_DEBUG_GHOST) {
+ debug.flags |= GHOST_kDebugDefault;
}
+ GHOST_SystemInitDebug(g_system, debug);
}
void wm_ghost_exit(void)
@@ -1925,6 +1953,9 @@ void WM_window_pixel_sample_read(const wmWindowManager *wm,
uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
{
+ /* WARNING: Reading from the front-buffer immediately after drawing may fail,
+ * for a slower but more reliable version of this function #WM_window_pixels_read_offscreen
+ * should be preferred. See it's comments for details on why it's needed, see also T98462. */
bool setup_context = wm->windrawable != win;
if (setup_context) {
@@ -2006,36 +2037,40 @@ void WM_init_native_pixels(bool do_it)
void WM_init_tablet_api(void)
{
- if (g_system) {
- switch (U.tablet_api) {
- case USER_TABLET_NATIVE:
- GHOST_SetTabletAPI(g_system, GHOST_kTabletWinPointer);
- break;
- case USER_TABLET_WINTAB:
- GHOST_SetTabletAPI(g_system, GHOST_kTabletWintab);
- break;
- case USER_TABLET_AUTOMATIC:
- default:
- GHOST_SetTabletAPI(g_system, GHOST_kTabletAutomatic);
- break;
- }
+ if (UNLIKELY(!g_system)) {
+ return;
+ }
+
+ switch (U.tablet_api) {
+ case USER_TABLET_NATIVE:
+ GHOST_SetTabletAPI(g_system, GHOST_kTabletWinPointer);
+ break;
+ case USER_TABLET_WINTAB:
+ GHOST_SetTabletAPI(g_system, GHOST_kTabletWintab);
+ break;
+ case USER_TABLET_AUTOMATIC:
+ default:
+ GHOST_SetTabletAPI(g_system, GHOST_kTabletAutomatic);
+ break;
}
}
void WM_cursor_warp(wmWindow *win, int x, int y)
{
- if (win && win->ghostwin) {
- int oldx = x, oldy = y;
+ if (!(win && win->ghostwin)) {
+ return;
+ }
- wm_cursor_position_to_ghost_client_coords(win, &x, &y);
- GHOST_SetCursorPosition(g_system, win->ghostwin, x, y);
+ int oldx = x, oldy = y;
- win->eventstate->prev_xy[0] = oldx;
- win->eventstate->prev_xy[1] = oldy;
+ wm_cursor_position_to_ghost_client_coords(win, &x, &y);
+ GHOST_SetCursorPosition(g_system, win->ghostwin, x, y);
- win->eventstate->xy[0] = oldx;
- win->eventstate->xy[1] = oldy;
- }
+ win->eventstate->prev_xy[0] = oldx;
+ win->eventstate->prev_xy[1] = oldy;
+
+ win->eventstate->xy[0] = oldx;
+ win->eventstate->xy[1] = oldy;
}
/** \} */