Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_window.c
| Show First 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | static struct WMInitStruct { | ||||
| bool native_pixels; | bool native_pixels; | ||||
| } wm_init_state = { | } wm_init_state = { | ||||
| .windowstate = GHOST_WINDOW_STATE_DEFAULT, | .windowstate = GHOST_WINDOW_STATE_DEFAULT, | ||||
| .window_focus = true, | .window_focus = true, | ||||
| .native_pixels = true, | .native_pixels = true, | ||||
| }; | }; | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Modifier Constants | |||||
| * \{ */ | |||||
| static const struct { | |||||
| uint8_t flag; | |||||
| GHOST_TKey ghost_key_pair[2]; | |||||
| GHOST_TModifierKey ghost_mask_pair[2]; | |||||
| } g_modifier_table[] = { | |||||
| {KM_SHIFT, | |||||
| {GHOST_kKeyLeftShift, GHOST_kKeyRightShift}, | |||||
| {GHOST_kModifierKeyLeftShift, GHOST_kModifierKeyRightShift}}, | |||||
| {KM_CTRL, | |||||
| {GHOST_kKeyLeftControl, GHOST_kKeyRightControl}, | |||||
| {GHOST_kModifierKeyLeftControl, GHOST_kModifierKeyRightControl}}, | |||||
| {KM_ALT, | |||||
| {GHOST_kKeyLeftAlt, GHOST_kKeyRightAlt}, | |||||
| {GHOST_kModifierKeyLeftAlt, GHOST_kModifierKeyRightAlt}}, | |||||
| {KM_OSKEY, | |||||
| {GHOST_kKeyLeftOS, GHOST_kKeyRightOS}, | |||||
| {GHOST_kModifierKeyLeftOS, GHOST_kModifierKeyRightOS}}, | |||||
| }; | |||||
| enum ModSide { | |||||
| MOD_SIDE_LEFT = 0, | |||||
| MOD_SIDE_RIGHT = 1, | |||||
| }; | |||||
| /** \} */ | |||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \name Window Open & Close | /** \name Window Open & Close | ||||
| * \{ */ | * \{ */ | ||||
| static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate); | static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate); | ||||
| static bool wm_window_timer(const bContext *C); | static bool wm_window_timer(const bContext *C); | ||||
| void wm_get_screensize(int *r_width, int *r_height) | void wm_get_screensize(int *r_width, int *r_height) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 833 Lines • ▼ Show 20 Lines | if (UNLIKELY(G.f & G_FLAG_EVENT_SIMULATE)) { | ||||
| *r_x = win->eventstate->xy[0]; | *r_x = win->eventstate->xy[0]; | ||||
| *r_y = win->eventstate->xy[1]; | *r_y = win->eventstate->xy[1]; | ||||
| return; | return; | ||||
| } | } | ||||
| GHOST_GetCursorPosition(g_system, win->ghostwin, r_x, r_y); | GHOST_GetCursorPosition(g_system, win->ghostwin, r_x, r_y); | ||||
| wm_cursor_position_from_ghost_client_coords(win, r_x, r_y); | wm_cursor_position_from_ghost_client_coords(win, r_x, r_y); | ||||
| } | } | ||||
| typedef enum { | |||||
| SHIFT = 's', | |||||
| CONTROL = 'c', | |||||
| ALT = 'a', | |||||
| OS = 'C', | |||||
| } modifierKeyType; | |||||
| /** Check if specified modifier key type is pressed. */ | /** Check if specified modifier key type is pressed. */ | ||||
| static bool query_qual(modifierKeyType qual) | static uint8_t wm_ghost_modifier_query(const enum ModSide side) | ||||
| { | { | ||||
| GHOST_TModifierKey left, right; | uint8_t result = 0; | ||||
| switch (qual) { | for (int i = 0; i < ARRAY_SIZE(g_modifier_table); i++) { | ||||
| case SHIFT: | |||||
| left = GHOST_kModifierKeyLeftShift; | |||||
| right = GHOST_kModifierKeyRightShift; | |||||
| break; | |||||
| case CONTROL: | |||||
| left = GHOST_kModifierKeyLeftControl; | |||||
| right = GHOST_kModifierKeyRightControl; | |||||
| break; | |||||
| case OS: | |||||
| left = right = GHOST_kModifierKeyOS; | |||||
| break; | |||||
| case ALT: | |||||
| default: | |||||
| left = GHOST_kModifierKeyLeftAlt; | |||||
| right = GHOST_kModifierKeyRightAlt; | |||||
| break; | |||||
| } | |||||
| bool val = false; | bool val = false; | ||||
| GHOST_GetModifierKeyState(g_system, left, &val); | GHOST_GetModifierKeyState(g_system, g_modifier_table[i].ghost_mask_pair[side], &val); | ||||
| if (!val) { | if (val) { | ||||
| GHOST_GetModifierKeyState(g_system, right, &val); | result |= g_modifier_table[i].flag; | ||||
| } | } | ||||
| } | |||||
| return val; | return result; | ||||
| } | } | ||||
| static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate) | static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate) | ||||
| { | { | ||||
| BLI_assert(ELEM(wm->windrawable, NULL, win)); | BLI_assert(ELEM(wm->windrawable, NULL, win)); | ||||
| wm->windrawable = win; | wm->windrawable = win; | ||||
| if (activate) { | if (activate) { | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | else { | ||||
| wmWindow *win = GHOST_GetWindowUserData(ghostwin); | wmWindow *win = GHOST_GetWindowUserData(ghostwin); | ||||
| switch (type) { | switch (type) { | ||||
| case GHOST_kEventWindowDeactivate: | case GHOST_kEventWindowDeactivate: | ||||
| wm_event_add_ghostevent(wm, win, type, data); | wm_event_add_ghostevent(wm, win, type, data); | ||||
| win->active = 0; /* XXX */ | win->active = 0; /* XXX */ | ||||
| break; | break; | ||||
| case GHOST_kEventWindowActivate: { | case GHOST_kEventWindowActivate: { | ||||
| const int keymodifier = ((query_qual(SHIFT) ? KM_SHIFT : 0) | | |||||
| (query_qual(CONTROL) ? KM_CTRL : 0) | | |||||
| (query_qual(ALT) ? KM_ALT : 0) | (query_qual(OS) ? KM_OSKEY : 0)); | |||||
| /* No context change! C->wm->windrawable is drawable, or for area queues. */ | /* No context change! C->wm->windrawable is drawable, or for area queues. */ | ||||
| wm->winactive = win; | wm->winactive = win; | ||||
| win->active = 1; | win->active = 1; | ||||
| /* bad ghost support for modifier keys... so on activate we set the modifiers again */ | /* bad ghost support for modifier keys... so on activate we set the modifiers again */ | ||||
| /* TODO: This is not correct since a modifier may be held when a window is activated... | const uint8_t keymodifier_sided[2] = { | ||||
| * better solve this at ghost level. attempted fix r54450 but it caused bug T34255. | wm_ghost_modifier_query(MOD_SIDE_LEFT), | ||||
| * | wm_ghost_modifier_query(MOD_SIDE_RIGHT), | ||||
| * For now don't send GHOST_kEventKeyDown events, just set the 'eventstate'. | }; | ||||
| */ | const uint8_t keymodifier = keymodifier_sided[0] | keymodifier_sided[1]; | ||||
| const uint8_t keymodifier_eventstate = win->eventstate->modifier; | |||||
| if (keymodifier != keymodifier_eventstate) { | |||||
| GHOST_TEventKeyData kdata = { | GHOST_TEventKeyData kdata = { | ||||
| .key = GHOST_kKeyUnknown, | .key = GHOST_kKeyUnknown, | ||||
| .utf8_buf = {'\0'}, | .utf8_buf = {'\0'}, | ||||
| .is_repeat = false, | .is_repeat = false, | ||||
| }; | }; | ||||
| if (win->eventstate->modifier & KM_SHIFT) { | for (int i = 0; i < ARRAY_SIZE(g_modifier_table); i++) { | ||||
| if ((keymodifier & KM_SHIFT) == 0) { | if (keymodifier_eventstate & g_modifier_table[i].flag) { | ||||
| kdata.key = GHOST_kKeyLeftShift; | if ((keymodifier & g_modifier_table[i].flag) == 0) { | ||||
| for (int side = 0; side < 2; side++) { | |||||
| if ((keymodifier_sided[side] & g_modifier_table[i].flag) == 0) { | |||||
| kdata.key = g_modifier_table[i].ghost_key_pair[side]; | |||||
| wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata); | wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata); | ||||
| /* Only ever send one release event | |||||
| * (currently releasing multiple isn't needed and only confuses logic). */ | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| #ifdef USE_WIN_ACTIVATE | |||||
| else { | |||||
| if (keymodifier & KM_SHIFT) { | |||||
| win->eventstate->modifier |= KM_SHIFT; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| if (win->eventstate->modifier & KM_CTRL) { | |||||
| if ((keymodifier & KM_CTRL) == 0) { | |||||
| kdata.key = GHOST_kKeyLeftControl; | |||||
| wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata); | |||||
| } | |||||
| } | |||||
| #ifdef USE_WIN_ACTIVATE | |||||
| else { | |||||
| if (keymodifier & KM_CTRL) { | |||||
| win->eventstate->modifier |= KM_CTRL; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| if (win->eventstate->modifier & KM_ALT) { | |||||
| if ((keymodifier & KM_ALT) == 0) { | |||||
| kdata.key = GHOST_kKeyLeftAlt; | |||||
| wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata); | |||||
| } | } | ||||
| } | } | ||||
| #ifdef USE_WIN_ACTIVATE | #ifdef USE_WIN_ACTIVATE | ||||
| else { | else { | ||||
| if (keymodifier & KM_ALT) { | if (keymodifier & g_modifier_table[i].flag) { | ||||
| win->eventstate->modifier |= KM_ALT; | for (int side = 0; side < 2; side++) { | ||||
| if (keymodifier_sided[side] & g_modifier_table[i].flag) { | |||||
| kdata.key = g_modifier_table[i].ghost_key_pair[side]; | |||||
| wm_event_add_ghostevent(wm, win, GHOST_kEventKeyDown, &kdata); | |||||
| } | } | ||||
| } | } | ||||
| #endif | |||||
| if (win->eventstate->modifier & KM_OSKEY) { | |||||
| if ((keymodifier & KM_OSKEY) == 0) { | |||||
| kdata.key = GHOST_kKeyOS; | |||||
| wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata); | |||||
| } | |||||
| } | |||||
| #ifdef USE_WIN_ACTIVATE | |||||
| else { | |||||
| if (keymodifier & KM_OSKEY) { | |||||
| win->eventstate->modifier |= KM_OSKEY; | |||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| #undef USE_WIN_ACTIVATE | #undef USE_WIN_ACTIVATE | ||||
| } | |||||
| } | |||||
| /* keymodifier zero, it hangs on hotkeys that open windows otherwise */ | /* keymodifier zero, it hangs on hotkeys that open windows otherwise */ | ||||
| win->eventstate->keymodifier = 0; | win->eventstate->keymodifier = 0; | ||||
| /* entering window, update mouse pos. but no event */ | /* entering window, update mouse pos. but no event */ | ||||
| wm_window_update_eventstate(win); | wm_window_update_eventstate(win); | ||||
| win->addmousemove = 1; /* enables highlighted buttons */ | win->addmousemove = 1; /* enables highlighted buttons */ | ||||
| ▲ Show 20 Lines • Show All 1,189 Lines • Show Last 20 Lines | |||||