Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_event_system.c
| Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_idprop.h" | #include "BKE_idprop.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_workspace.h" | |||||
| #include "BKE_sound.h" | #include "BKE_sound.h" | ||||
| #include "ED_fileselect.h" | #include "ED_fileselect.h" | ||||
| #include "ED_info.h" | #include "ED_info.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "ED_util.h" | #include "ED_util.h" | ||||
| ▲ Show 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | void wm_event_do_notifiers(bContext *C) | ||||
| wmWindow *win; | wmWindow *win; | ||||
| uint64_t win_combine_v3d_datamask = 0; | uint64_t win_combine_v3d_datamask = 0; | ||||
| if (wm == NULL) | if (wm == NULL) | ||||
| return; | return; | ||||
| /* cache & catch WM level notifiers, such as frame change, scene/screen set */ | /* cache & catch WM level notifiers, such as frame change, scene/screen set */ | ||||
| for (win = wm->windows.first; win; win = win->next) { | for (win = wm->windows.first; win; win = win->next) { | ||||
| Scene *scene = WM_window_get_active_scene(win); | |||||
| bool do_anim = false; | bool do_anim = false; | ||||
| CTX_wm_window_set(C, win); | CTX_wm_window_set(C, win); | ||||
| for (note = wm->queue.first; note; note = next) { | for (note = wm->queue.first; note; note = next) { | ||||
| next = note->next; | next = note->next; | ||||
| if (note->category == NC_WM) { | if (note->category == NC_WM) { | ||||
| if (ELEM(note->data, ND_FILEREAD, ND_FILESAVE)) { | if (ELEM(note->data, ND_FILEREAD, ND_FILESAVE)) { | ||||
| wm->file_saved = 1; | wm->file_saved = 1; | ||||
| wm_window_title(wm, win); | wm_window_title(wm, win); | ||||
| } | } | ||||
| else if (note->data == ND_DATACHANGED) | else if (note->data == ND_DATACHANGED) | ||||
| wm_window_title(wm, win); | wm_window_title(wm, win); | ||||
| } | } | ||||
| if (note->window == win) { | if (note->window == win) { | ||||
| if (note->category == NC_SCREEN) { | if (note->category == NC_SCREEN) { | ||||
| if (note->data == ND_SCREENBROWSE) { | if (note->data == ND_WORKSPACE_SET) { | ||||
| WorkSpace *ref_ws = note->reference; | |||||
| UI_popup_handlers_remove_all(C, &win->modalhandlers); | |||||
| ED_workspace_change(ref_ws, C, wm, win); | |||||
| if (G.debug & G_DEBUG_EVENTS) | |||||
| printf("%s: Workspace set %p\n", __func__, note->reference); | |||||
| } | |||||
| else if (note->data == ND_LAYOUTBROWSE) { | |||||
| bScreen *ref_screen = BKE_workspace_layout_screen_get(note->reference); | |||||
| /* free popup handlers only [#35434] */ | /* free popup handlers only [#35434] */ | ||||
| UI_popup_handlers_remove_all(C, &win->modalhandlers); | UI_popup_handlers_remove_all(C, &win->modalhandlers); | ||||
| ED_screen_set(C, note->reference); // XXX hrms, think this over! | ED_screen_change(C, ref_screen); /* XXX hrms, think this over! */ | ||||
| if (G.debug & G_DEBUG_EVENTS) | if (G.debug & G_DEBUG_EVENTS) | ||||
| printf("%s: screen set %p\n", __func__, note->reference); | printf("%s: screen set %p\n", __func__, note->reference); | ||||
| } | } | ||||
| else if (note->data == ND_SCREENDELETE) { | else if (note->data == ND_LAYOUTDELETE) { | ||||
| ED_screen_delete(C, note->reference); // XXX hrms, think this over! | WorkSpace *workspace = WM_window_get_active_workspace(win); | ||||
| WorkSpaceLayout *layout = note->reference; | |||||
| ED_workspace_layout_delete(workspace, layout, C); // XXX hrms, think this over! | |||||
| if (G.debug & G_DEBUG_EVENTS) | if (G.debug & G_DEBUG_EVENTS) | ||||
| printf("%s: screen delete %p\n", __func__, note->reference); | printf("%s: screen delete %p\n", __func__, note->reference); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (note->window == win || | if (note->window == win || | ||||
| (note->window == NULL && (note->reference == NULL || note->reference == win->screen->scene))) | (note->window == NULL && (note->reference == NULL || note->reference == scene))) | ||||
| { | { | ||||
| if (note->category == NC_SCENE) { | if (note->category == NC_SCENE) { | ||||
| if (note->data == ND_FRAME) | if (note->data == ND_FRAME) | ||||
| do_anim = true; | do_anim = true; | ||||
| } | } | ||||
| } | } | ||||
| if (ELEM(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_WM)) { | if (ELEM(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_WM)) { | ||||
| SceneLayer *sl = BKE_scene_layer_context_active(win->screen->scene); | SceneLayer *sl = BKE_scene_layer_context_active(scene); | ||||
| ED_info_stats_clear(sl); | ED_info_stats_clear(sl); | ||||
| WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL); | WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL); | ||||
| } | } | ||||
| } | } | ||||
| if (do_anim) { | if (do_anim) { | ||||
| /* XXX, quick frame changes can cause a crash if framechange and rendering | /* XXX, quick frame changes can cause a crash if framechange and rendering | ||||
| * collide (happens on slow scenes), BKE_scene_update_for_newframe can be called | * collide (happens on slow scenes), BKE_scene_update_for_newframe can be called | ||||
| * twice which can depgraph update the same object at once */ | * twice which can depgraph update the same object at once */ | ||||
| if (G.is_rendering == false) { | if (G.is_rendering == false) { | ||||
| /* depsgraph gets called, might send more notifiers */ | /* depsgraph gets called, might send more notifiers */ | ||||
| ED_update_for_newframe(CTX_data_main(C), win->screen->scene, 1); | ED_update_for_newframe(CTX_data_main(C), scene, 1); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* the notifiers are sent without context, to keep it clean */ | /* the notifiers are sent without context, to keep it clean */ | ||||
| while ((note = BLI_pophead(&wm->queue))) { | while ((note = BLI_pophead(&wm->queue))) { | ||||
| for (win = wm->windows.first; win; win = win->next) { | for (win = wm->windows.first; win; win = win->next) { | ||||
| Scene *scene = win->screen->scene; | Scene *scene = WM_window_get_active_scene(win); | ||||
| bScreen *screen = WM_window_get_active_screen(win); | |||||
| /* filter out notifiers */ | /* filter out notifiers */ | ||||
| if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) { | if (note->category == NC_SCREEN && | ||||
| note->reference && | |||||
| note->reference != screen && | |||||
| note->reference != WM_window_get_active_workspace(win) && | |||||
| note->reference != WM_window_get_active_layout(win)) | |||||
| { | |||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if (note->category == NC_SCENE && note->reference && note->reference != scene) { | else if (note->category == NC_SCENE && note->reference && note->reference != scene) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else { | else { | ||||
| ScrArea *sa; | ScrArea *sa; | ||||
| ARegion *ar; | ARegion *ar; | ||||
| /* XXX context in notifiers? */ | /* XXX context in notifiers? */ | ||||
| CTX_wm_window_set(C, win); | CTX_wm_window_set(C, win); | ||||
| /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name + 2, note->category); */ | /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name + 2, note->category); */ | ||||
| ED_screen_do_listen(C, note); | ED_screen_do_listen(C, note); | ||||
| for (ar = win->screen->regionbase.first; ar; ar = ar->next) { | for (ar = screen->regionbase.first; ar; ar = ar->next) { | ||||
| ED_region_do_listen(win->screen, NULL, ar, note, scene); | ED_region_do_listen(screen, NULL, ar, note, scene); | ||||
| } | } | ||||
| for (sa = win->screen->areabase.first; sa; sa = sa->next) { | for (sa = screen->areabase.first; sa; sa = sa->next) { | ||||
| ED_area_do_listen(win->screen, sa, note, scene); | ED_area_do_listen(screen, sa, note, scene); | ||||
| for (ar = sa->regionbase.first; ar; ar = ar->next) { | for (ar = sa->regionbase.first; ar; ar = ar->next) { | ||||
| ED_region_do_listen(win->screen, sa, ar, note, scene); | ED_region_do_listen(screen, sa, ar, note, scene); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(note); | MEM_freeN(note); | ||||
| } | } | ||||
| /* combine datamasks so 1 win doesn't disable UV's in another [#26448] */ | /* combine datamasks so 1 win doesn't disable UV's in another [#26448] */ | ||||
| for (win = wm->windows.first; win; win = win->next) { | for (win = wm->windows.first; win; win = win->next) { | ||||
| win_combine_v3d_datamask |= ED_view3d_screen_datamask(win->screen); | const Scene *scene = WM_window_get_active_scene(win); | ||||
| const bScreen *screen = WM_window_get_active_screen(win); | |||||
| win_combine_v3d_datamask |= ED_view3d_screen_datamask(scene, screen); | |||||
| } | } | ||||
| /* cached: editor refresh callbacks now, they get context */ | /* cached: editor refresh callbacks now, they get context */ | ||||
| for (win = wm->windows.first; win; win = win->next) { | for (win = wm->windows.first; win; win = win->next) { | ||||
| const bScreen *screen = WM_window_get_active_screen(win); | |||||
| Scene *scene = WM_window_get_active_scene(win); | |||||
| ScrArea *sa; | ScrArea *sa; | ||||
| CTX_wm_window_set(C, win); | CTX_wm_window_set(C, win); | ||||
| for (sa = win->screen->areabase.first; sa; sa = sa->next) { | for (sa = screen->areabase.first; sa; sa = sa->next) { | ||||
| if (sa->do_refresh) { | if (sa->do_refresh) { | ||||
| CTX_wm_area_set(C, sa); | CTX_wm_area_set(C, sa); | ||||
| ED_area_do_refresh(C, sa); | ED_area_do_refresh(C, sa); | ||||
| } | } | ||||
| } | } | ||||
| /* XXX make lock in future, or separated derivedmesh users in scene */ | /* XXX make lock in future, or separated derivedmesh users in scene */ | ||||
| if (G.is_rendering == false) { | if (G.is_rendering == false) { | ||||
| /* depsgraph & animation: update tagged datablocks */ | /* depsgraph & animation: update tagged datablocks */ | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| /* copied to set's in scene_update_tagged_recursive() */ | /* copied to set's in scene_update_tagged_recursive() */ | ||||
| win->screen->scene->customdata_mask = win_combine_v3d_datamask; | scene->customdata_mask = win_combine_v3d_datamask; | ||||
| /* XXX, hack so operators can enforce datamasks [#26482], gl render */ | /* XXX, hack so operators can enforce datamasks [#26482], gl render */ | ||||
| win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal; | scene->customdata_mask |= scene->customdata_mask_modal; | ||||
| BKE_scene_update_tagged(bmain->eval_ctx, bmain, win->screen->scene); | BKE_scene_update_tagged(bmain->eval_ctx, bmain, scene); | ||||
| } | } | ||||
| } | } | ||||
| CTX_wm_window_set(C, NULL); | CTX_wm_window_set(C, NULL); | ||||
| } | } | ||||
| static int wm_event_always_pass(const wmEvent *event) | static int wm_event_always_pass(const wmEvent *event) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 1,942 Lines • ▼ Show 20 Lines | if (ar == NULL || !BLI_rcti_isect_pt_v(&ar->winrct, &event->prevx)) { | ||||
| CTX_wm_area_set(C, sa); | CTX_wm_area_set(C, sa); | ||||
| CTX_wm_region_set(C, ar); | CTX_wm_region_set(C, ar); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *event) | static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *event) | ||||
| { | { | ||||
| bScreen *screen = WM_window_get_active_screen(win); | |||||
| if (BLI_listbase_is_empty(&wm->drags)) { | if (BLI_listbase_is_empty(&wm->drags)) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (event->type == MOUSEMOVE || ISKEYMODIFIER(event->type)) { | if (event->type == MOUSEMOVE || ISKEYMODIFIER(event->type)) { | ||||
| win->screen->do_draw_drag = true; | screen->do_draw_drag = true; | ||||
| } | } | ||||
| else if (event->type == ESCKEY) { | else if (event->type == ESCKEY) { | ||||
| WM_drag_free_list(&wm->drags); | WM_drag_free_list(&wm->drags); | ||||
| win->screen->do_draw_drag = true; | screen->do_draw_drag = true; | ||||
| } | } | ||||
| else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { | else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { | ||||
| event->type = EVT_DROP; | event->type = EVT_DROP; | ||||
| /* create customdata, first free existing */ | /* create customdata, first free existing */ | ||||
| if (event->customdata) { | if (event->customdata) { | ||||
| if (event->customdatafree) | if (event->customdatafree) | ||||
| MEM_freeN(event->customdata); | MEM_freeN(event->customdata); | ||||
| } | } | ||||
| event->custom = EVT_DATA_DRAGDROP; | event->custom = EVT_DATA_DRAGDROP; | ||||
| event->customdata = &wm->drags; | event->customdata = &wm->drags; | ||||
| event->customdatafree = 1; | event->customdatafree = 1; | ||||
| /* clear drop icon */ | /* clear drop icon */ | ||||
| win->screen->do_draw_drag = true; | screen->do_draw_drag = true; | ||||
| /* restore cursor (disabled, see wm_dragdrop.c) */ | /* restore cursor (disabled, see wm_dragdrop.c) */ | ||||
| // WM_cursor_modal_restore(win); | // WM_cursor_modal_restore(win); | ||||
| } | } | ||||
| /* overlap fails otherwise */ | /* overlap fails otherwise */ | ||||
| if (win->screen->do_draw_drag) | if (screen->do_draw_drag) | ||||
| if (win->drawmethod == USER_DRAW_OVERLAP) | if (win->drawmethod == USER_DRAW_OVERLAP) | ||||
| win->screen->do_draw = true; | screen->do_draw = true; | ||||
| } | } | ||||
| /* filter out all events of the pie that spawned the last pie unless it's a release event */ | /* filter out all events of the pie that spawned the last pie unless it's a release event */ | ||||
| static bool wm_event_pie_filter(wmWindow *win, const wmEvent *event) | static bool wm_event_pie_filter(wmWindow *win, const wmEvent *event) | ||||
| { | { | ||||
| if (win->lock_pie_event && win->lock_pie_event == event->type) { | if (win->lock_pie_event && win->lock_pie_event == event->type) { | ||||
| if (event->val == KM_RELEASE) { | if (event->val == KM_RELEASE) { | ||||
| Show All 15 Lines | |||||
| { | { | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| wmWindow *win; | wmWindow *win; | ||||
| /* update key configuration before handling events */ | /* update key configuration before handling events */ | ||||
| WM_keyconfig_update(wm); | WM_keyconfig_update(wm); | ||||
| for (win = wm->windows.first; win; win = win->next) { | for (win = wm->windows.first; win; win = win->next) { | ||||
| bScreen *screen = WM_window_get_active_screen(win); | |||||
| wmEvent *event; | wmEvent *event; | ||||
| if (win->screen == NULL) | /* some safty checks - these should always be set! */ | ||||
| BLI_assert(WM_window_get_active_scene(win)); | |||||
| BLI_assert(WM_window_get_active_screen(win)); | |||||
| BLI_assert(WM_window_get_active_workspace(win)); | |||||
| if (screen == NULL) | |||||
| wm_event_free_all(win); | wm_event_free_all(win); | ||||
| else { | else { | ||||
| Scene *scene = win->screen->scene; | Scene *scene = WM_window_get_active_scene(win); | ||||
| if (scene) { | if (scene) { | ||||
| int is_playing_sound = BKE_sound_scene_playing(win->screen->scene); | int is_playing_sound = BKE_sound_scene_playing(scene); | ||||
| if (is_playing_sound != -1) { | if (is_playing_sound != -1) { | ||||
| bool is_playing_screen; | bool is_playing_screen; | ||||
| CTX_wm_window_set(C, win); | CTX_wm_window_set(C, win); | ||||
| CTX_wm_screen_set(C, win->screen); | |||||
| CTX_data_scene_set(C, scene); | CTX_data_scene_set(C, scene); | ||||
| is_playing_screen = (ED_screen_animation_playing(wm) != NULL); | is_playing_screen = (ED_screen_animation_playing(wm) != NULL); | ||||
| if (((is_playing_sound == 1) && (is_playing_screen == 0)) || | if (((is_playing_sound == 1) && (is_playing_screen == 0)) || | ||||
| ((is_playing_sound == 0) && (is_playing_screen == 1))) | ((is_playing_sound == 0) && (is_playing_screen == 1))) | ||||
| { | { | ||||
| ED_screen_animation_play(C, -1, 1); | ED_screen_animation_play(C, -1, 1); | ||||
| Show All 16 Lines | else { | ||||
| CTX_wm_window_set(C, NULL); | CTX_wm_window_set(C, NULL); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| while ( (event = win->queue.first) ) { | while ( (event = win->queue.first) ) { | ||||
| int action = WM_HANDLER_CONTINUE; | int action = WM_HANDLER_CONTINUE; | ||||
| /* active screen might change during handlers, update pointer */ | |||||
| screen = WM_window_get_active_screen(win); | |||||
| if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { | if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { | ||||
| printf("\n%s: Handling event\n", __func__); | printf("\n%s: Handling event\n", __func__); | ||||
| WM_event_print(event); | WM_event_print(event); | ||||
| } | } | ||||
| /* take care of pie event filter */ | /* take care of pie event filter */ | ||||
| if (wm_event_pie_filter(win, event)) { | if (wm_event_pie_filter(win, event)) { | ||||
| if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { | if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | while ( (event = win->queue.first) ) { | ||||
| wm_paintcursor_test(C, event); | wm_paintcursor_test(C, event); | ||||
| } | } | ||||
| #ifdef WITH_INPUT_NDOF | #ifdef WITH_INPUT_NDOF | ||||
| else if (event->type == NDOF_MOTION) { | else if (event->type == NDOF_MOTION) { | ||||
| win->addmousemove = true; | win->addmousemove = true; | ||||
| } | } | ||||
| #endif | #endif | ||||
| for (sa = win->screen->areabase.first; sa; sa = sa->next) { | for (sa = screen->areabase.first; sa; sa = sa->next) { | ||||
| /* after restoring a screen from SCREENMAXIMIZED we have to wait | /* after restoring a screen from SCREENMAXIMIZED we have to wait | ||||
| * with the screen handling till the region coordinates are updated */ | * with the screen handling till the region coordinates are updated */ | ||||
| if (win->screen->skip_handling == true) { | if (screen->skip_handling == true) { | ||||
| /* restore for the next iteration of wm_event_do_handlers */ | /* restore for the next iteration of wm_event_do_handlers */ | ||||
| win->screen->skip_handling = false; | screen->skip_handling = false; | ||||
| break; | break; | ||||
| } | } | ||||
| /* update azones if needed - done here because it needs to be independent from redraws */ | /* update azones if needed - done here because it needs to be independent from redraws */ | ||||
| if (sa->flag & AREA_FLAG_ACTIONZONES_UPDATE) { | if (sa->flag & AREA_FLAG_ACTIONZONES_UPDATE) { | ||||
| ED_area_azones_update(sa, &event->x); | ED_area_azones_update(sa, &event->x); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,224 Lines • Show Last 20 Lines | |||||