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')
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c15
-rw-r--r--source/blender/windowmanager/intern/wm_files.c71
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c69
-rw-r--r--source/blender/windowmanager/intern/wm_window.c25
5 files changed, 112 insertions, 70 deletions
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index cdb7b591907..11783ae3517 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -264,7 +264,7 @@ void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
if (wrap == WM_CURSOR_WRAP_X) {
mode_axis = GHOST_kAxisX;
}
- if (wrap == WM_CURSOR_WRAP_Y) {
+ else if (wrap == WM_CURSOR_WRAP_Y) {
mode_axis = GHOST_kGrabAxisY;
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 0d1f4cc4830..a6588c40f0f 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1048,7 +1048,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
wmWindowManager *wm = CTX_wm_manager(C);
int retval = OPERATOR_CANCELLED;
- CTX_wm_operator_poll_msg_set(C, NULL);
+ CTX_wm_operator_poll_msg_clear(C);
if (op == NULL || op->type == NULL) {
return retval;
@@ -1469,7 +1469,7 @@ static int wm_operator_call_internal(bContext *C,
{
int retval;
- CTX_wm_operator_poll_msg_set(C, NULL);
+ CTX_wm_operator_poll_msg_clear(C);
/* Dummy test. */
if (ot) {
@@ -4478,16 +4478,21 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void
event.prevtype = event.type;
event.prevval = event.val;
- /* Ensure the event state is correct, any deviation from this may cause bugs. */
+ /* Ensure the event state is correct, any deviation from this may cause bugs.
+ *
+ * NOTE: #EVENT_NONE is set when unknown keys are pressed,
+ * while not common, avoid a false alarm. */
#ifndef NDEBUG
if ((event_state->type || event_state->val) && /* Ignore cleared event state. */
- !(ISMOUSE_BUTTON(event_state->type) || ISKEYBOARD(event_state->type))) {
+ !(ISMOUSE_BUTTON(event_state->type) || ISKEYBOARD(event_state->type) ||
+ (event_state->type == EVENT_NONE))) {
CLOG_WARN(WM_LOG_HANDLERS,
"Non-keyboard/mouse button found in 'win->eventstate->type = %d'",
event_state->type);
}
if ((event_state->prevtype || event_state->prevval) && /* Ignore cleared event state. */
- !(ISMOUSE_BUTTON(event_state->prevtype) || ISKEYBOARD(event_state->prevtype))) {
+ !(ISMOUSE_BUTTON(event_state->prevtype) || ISKEYBOARD(event_state->prevtype) ||
+ (event_state->type == EVENT_NONE))) {
CLOG_WARN(WM_LOG_HANDLERS,
"Non-keyboard/mouse button found in 'win->eventstate->prevtype = %d'",
event_state->prevtype);
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index bbcb0669cce..d0ee7075516 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -2157,21 +2157,9 @@ static void wm_homefile_read_after_dialog_callback(bContext *C, void *user_data)
C, "WM_OT_read_homefile", WM_OP_EXEC_DEFAULT, (IDProperty *)user_data);
}
-static void wm_free_operator_properties_callback(void *user_data)
-{
- IDProperty *properties = (IDProperty *)user_data;
- IDP_FreeProperty(properties);
-}
-
static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- if (U.uiflag & USER_SAVE_PROMPT &&
- wm_file_or_image_is_modified(CTX_data_main(C), CTX_wm_manager(C))) {
- wmGenericCallback *callback = MEM_callocN(sizeof(*callback), __func__);
- callback->exec = wm_homefile_read_after_dialog_callback;
- callback->user_data = IDP_CopyProperty(op->properties);
- callback->free_user_data = wm_free_operator_properties_callback;
- wm_close_file_dialog(C, callback);
+ if (wm_operator_close_file_dialog_if_needed(C, op, wm_homefile_read_after_dialog_callback)) {
return OPERATOR_INTERFACE;
}
return wm_homefile_read_exec(C, op);
@@ -2331,13 +2319,7 @@ static int wm_open_mainfile__discard_changes(bContext *C, wmOperator *op)
set_next_operator_state(op, OPEN_MAINFILE_STATE_OPEN);
}
- if (U.uiflag & USER_SAVE_PROMPT &&
- wm_file_or_image_is_modified(CTX_data_main(C), CTX_wm_manager(C))) {
- wmGenericCallback *callback = MEM_callocN(sizeof(*callback), __func__);
- callback->exec = wm_open_mainfile_after_dialog_callback;
- callback->user_data = IDP_CopyProperty(op->properties);
- callback->free_user_data = wm_free_operator_properties_callback;
- wm_close_file_dialog(C, callback);
+ if (wm_operator_close_file_dialog_if_needed(C, op, wm_open_mainfile_after_dialog_callback)) {
return OPERATOR_INTERFACE;
}
return wm_open_mainfile_dispatch(C, op);
@@ -2637,12 +2619,25 @@ static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int wm_recover_last_session_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static void wm_recover_last_session_after_dialog_callback(bContext *C, void *user_data)
+{
+ WM_operator_name_call_with_properties(
+ C, "WM_OT_recover_last_session", WM_OP_EXEC_DEFAULT, (IDProperty *)user_data);
+}
+
+static int wm_recover_last_session_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *UNUSED(event))
{
/* Keep the current setting instead of using the preferences since a file selector
* doesn't give us the option to change the setting. */
wm_open_init_use_scripts(op, false);
- return WM_operator_confirm(C, op, event);
+
+ if (wm_operator_close_file_dialog_if_needed(
+ C, op, wm_recover_last_session_after_dialog_callback)) {
+ return OPERATOR_INTERFACE;
+ }
+ return wm_recover_last_session_exec(C, op);
}
void WM_OT_recover_last_session(wmOperatorType *ot)
@@ -3270,7 +3265,10 @@ static void wm_block_file_close_save(bContext *C, void *arg_block, void *arg_dat
bool file_has_been_saved_before = BKE_main_blendfile_path(bmain)[0] != '\0';
if (file_has_been_saved_before) {
- WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL);
+ if (WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL) &
+ OPERATOR_CANCELLED) {
+ execute_callback = false;
+ }
}
else {
WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_INVOKE_DEFAULT, NULL);
@@ -3456,4 +3454,31 @@ void wm_close_file_dialog(bContext *C, wmGenericCallback *post_action)
}
}
+static void wm_free_operator_properties_callback(void *user_data)
+{
+ IDProperty *properties = (IDProperty *)user_data;
+ IDP_FreeProperty(properties);
+}
+
+/**
+ * \return True if the dialog was created, the calling operator should return #OPERATOR_INTERFACE
+ * then.
+ */
+bool wm_operator_close_file_dialog_if_needed(bContext *C,
+ wmOperator *op,
+ wmGenericCallbackFn post_action_fn)
+{
+ if (U.uiflag & USER_SAVE_PROMPT &&
+ wm_file_or_image_is_modified(CTX_data_main(C), CTX_wm_manager(C))) {
+ wmGenericCallback *callback = MEM_callocN(sizeof(*callback), __func__);
+ callback->exec = post_action_fn;
+ callback->user_data = IDP_CopyProperty(op->properties);
+ callback->free_user_data = wm_free_operator_properties_callback;
+ wm_close_file_dialog(C, callback);
+ return true;
+ }
+
+ return false;
+}
+
/** \} */
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index fc69211c14d..7726eb1b5d3 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -244,7 +244,7 @@ typedef struct PlayAnimPict {
int IB_flags;
#ifdef USE_FRAME_CACHE_LIMIT
- /** Back pointer to the #LinkData node for this struct in the #inmempicsbase list. */
+ /** Back pointer to the #LinkData node for this struct in the #g_frame_cache.pics list. */
LinkData *frame_cache_node;
size_t size_in_memory;
#endif
@@ -259,13 +259,22 @@ static double fps_movie;
#endif
#ifdef USE_FRAME_CACHE_LIMIT
-static struct ListBase inmempicsbase = {NULL, NULL};
-/** Keep track of the memory used by #inmempicsbase when `frame_cache_memory_limit != 0`. */
-size_t inmempicsbase_size_in_memory = 0;
-static int added_images = 0;
-/** Limit the amount of memory used for cache (in bytes). */
-static size_t frame_cache_memory_limit = 0;
-#endif
+static struct {
+ /** A list of #LinkData nodes referencing #PlayAnimPict to track cached frames. */
+ struct ListBase pics;
+ /** Number if elements in `pics`. */
+ int pics_len;
+ /** Keep track of memory used by #g_frame_cache.pics when `g_frame_cache.memory_limit != 0`. */
+ size_t pics_size_in_memory;
+ /** Optionally limit the amount of memory used for cache (in bytes), ignored when zero. */
+ size_t memory_limit;
+} g_frame_cache = {
+ .pics = {NULL, NULL},
+ .pics_len = 0,
+ .pics_size_in_memory = 0,
+ .memory_limit = 0,
+};
+#endif /* USE_FRAME_CACHE_LIMIT */
static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step)
{
@@ -575,7 +584,7 @@ static void build_pict_list_ex(
*/
while (IMB_ispic(filepath) && totframes) {
- bool hasevent;
+ bool has_event;
size_t size;
int file;
@@ -656,7 +665,7 @@ static void build_pict_list_ex(
BLI_path_sequence_encode(
filepath, fp_decoded.head, fp_decoded.tail, fp_decoded.digits, fp_framenr);
- while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0))) {
+ while ((has_event = GHOST_ProcessEvents(g_WS.ghost_system, false))) {
GHOST_DispatchEvents(g_WS.ghost_system);
if (ps->loading == false) {
return;
@@ -1363,7 +1372,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
case 'c': {
#ifdef USE_FRAME_CACHE_LIMIT
const int memory_in_mb = max_ii(0, atoi(argv[2]));
- frame_cache_memory_limit = (size_t)memory_in_mb * (1024 * 1024);
+ g_frame_cache.memory_limit = (size_t)memory_in_mb * (1024 * 1024);
#endif
argc--;
argv++;
@@ -1536,7 +1545,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
#endif
while (ps.picture) {
- int hasevent;
+ bool has_event;
#ifndef USE_IMB_CACHE
if (ibuf != NULL && ibuf->ftype == IMB_FTYPE_NONE) {
IMB_freeImBuf(ibuf);
@@ -1566,43 +1575,43 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
#ifdef USE_FRAME_CACHE_LIMIT
if (ps.picture->frame_cache_node == NULL) {
ps.picture->frame_cache_node = BLI_genericNodeN(ps.picture);
- BLI_addhead(&inmempicsbase, ps.picture->frame_cache_node);
- added_images++;
+ BLI_addhead(&g_frame_cache.pics, ps.picture->frame_cache_node);
+ g_frame_cache.pics_len++;
- if (frame_cache_memory_limit != 0) {
+ if (g_frame_cache.memory_limit != 0) {
BLI_assert(ps.picture->size_in_memory == 0);
ps.picture->size_in_memory = IMB_get_size_in_memory(ps.picture->ibuf);
- inmempicsbase_size_in_memory += ps.picture->size_in_memory;
+ g_frame_cache.pics_size_in_memory += ps.picture->size_in_memory;
}
}
else {
/* Don't free the current frame by moving it to the head of the list. */
BLI_assert(ps.picture->frame_cache_node->data == ps.picture);
- BLI_remlink(&inmempicsbase, ps.picture->frame_cache_node);
- BLI_addhead(&inmempicsbase, ps.picture->frame_cache_node);
+ BLI_remlink(&g_frame_cache.pics, ps.picture->frame_cache_node);
+ BLI_addhead(&g_frame_cache.pics, ps.picture->frame_cache_node);
}
/* Really basic memory conservation scheme. Keep frames in a FIFO queue. */
- LinkData *node = inmempicsbase.last;
- while (node && (frame_cache_memory_limit ?
- (inmempicsbase_size_in_memory > frame_cache_memory_limit) :
- (added_images > PLAY_FRAME_CACHE_MAX))) {
+ LinkData *node = g_frame_cache.pics.last;
+ while (node && (g_frame_cache.memory_limit ?
+ (g_frame_cache.pics_size_in_memory > g_frame_cache.memory_limit) :
+ (g_frame_cache.pics_len > PLAY_FRAME_CACHE_MAX))) {
PlayAnimPict *pic = node->data;
BLI_assert(pic->frame_cache_node == node);
if (pic->ibuf && pic->ibuf != ibuf) {
LinkData *node_tmp;
IMB_freeImBuf(pic->ibuf);
- if (frame_cache_memory_limit != 0) {
+ if (g_frame_cache.memory_limit != 0) {
BLI_assert(pic->size_in_memory != 0);
- inmempicsbase_size_in_memory -= pic->size_in_memory;
+ g_frame_cache.pics_size_in_memory -= pic->size_in_memory;
pic->size_in_memory = 0;
}
pic->ibuf = NULL;
pic->frame_cache_node = NULL;
node_tmp = node->prev;
- BLI_freelinkN(&inmempicsbase, node);
- added_images--;
+ BLI_freelinkN(&g_frame_cache.pics, node);
+ g_frame_cache.pics_len--;
node = node_tmp;
}
else {
@@ -1641,14 +1650,14 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
ps.next_frame = ps.direction;
- while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0))) {
+ while ((has_event = GHOST_ProcessEvents(g_WS.ghost_system, false))) {
GHOST_DispatchEvents(g_WS.ghost_system);
}
if (ps.go == false) {
break;
}
change_frame(&ps);
- if (!hasevent) {
+ if (!has_event) {
PIL_sleep_ms(1);
}
if (ps.wait2) {
@@ -1719,8 +1728,8 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
BLI_freelistN(&picsbase);
#ifdef USE_FRAME_CACHE_LIMIT
- BLI_freelistN(&inmempicsbase);
- added_images = 0;
+ BLI_freelistN(&g_frame_cache.pics);
+ g_frame_cache.pics_len = 0;
#endif
#ifdef WITH_AUDASPACE
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 2e9fd1b1b16..cdd5ea12df8 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -133,7 +133,7 @@ static struct WMInitStruct {
* \{ */
static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate);
-static int wm_window_timer(const bContext *C);
+static bool wm_window_timer(const bContext *C);
/* XXX this one should correctly check for apple top header...
* done for Cocoa : returns window contents (and not frame) max size*/
@@ -1498,12 +1498,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
* Timer handlers should check for delta to decide if they just update, or follow real time.
* Timer handlers can also set duration to match frames passed
*/
-static int wm_window_timer(const bContext *C)
+static bool wm_window_timer(const bContext *C)
{
Main *bmain = CTX_data_main(C);
wmWindowManager *wm = CTX_wm_manager(C);
double time = PIL_check_seconds_timer();
- int retval = 0;
+ bool has_event = false;
/* Mutable in case the timer gets removed. */
LISTBASE_FOREACH_MUTABLE (wmTimer *, wt, &wm->timers) {
@@ -1540,31 +1540,34 @@ static int wm_window_timer(const bContext *C)
event.customdata = wt;
wm_event_add(win, &event);
- retval = 1;
+ has_event = true;
}
}
}
- return retval;
+ return has_event;
}
void wm_window_process_events(const bContext *C)
{
BLI_assert(BLI_thread_is_main());
- int hasevent = GHOST_ProcessEvents(g_system, 0); /* 0 is no wait */
+ bool has_event = GHOST_ProcessEvents(g_system, false); /* `false` is no wait. */
- if (hasevent) {
+ if (has_event) {
GHOST_DispatchEvents(g_system);
}
- hasevent |= wm_window_timer(C);
+ has_event |= wm_window_timer(C);
#ifdef WITH_XR_OPENXR
/* XR events don't use the regular window queues. So here we don't only trigger
* processing/dispatching but also handling. */
- hasevent |= wm_xr_events_handle(CTX_wm_manager(C));
+ has_event |= wm_xr_events_handle(CTX_wm_manager(C));
#endif
- /* no event, we sleep 5 milliseconds */
- if (hasevent == 0) {
+ /* When there is no event, sleep 5 milliseconds not to use too much CPU when idle.
+ *
+ * Skip sleeping when simulating events so tests don't idle unnecessarily as simulated
+ * events are typically generated from a timer that runs in the main loop. */
+ if ((has_event == false) && !(G.f & G_FLAG_EVENT_SIMULATE)) {
PIL_sleep_ms(5);
}
}