diff options
Diffstat (limited to 'source/blender/windowmanager/intern')
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 20 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 98 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 126 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_gesture.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 71 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 14 |
8 files changed, 222 insertions, 120 deletions
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 67e961b9cd0..a09cc4aeb31 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -430,7 +430,7 @@ void wm_clear_default_size(bContext *C) /* on startup, it adds all data, for matching */ void wm_add_default(bContext *C) { - wmWindowManager *wm = BKE_libblock_alloc(CTX_data_main(C), ID_WM, "WinMan"); + wmWindowManager *wm = BKE_libblock_alloc(CTX_data_main(C), ID_WM, "WinMan", 0); wmWindow *win; bScreen *screen = CTX_wm_screen(C); /* XXX from file read hrmf */ @@ -495,6 +495,10 @@ void wm_close_and_free_all(bContext *C, ListBase *wmlist) void WM_main(bContext *C) { + /* Single refresh before handling events. + * This ensures we don't run operators before the depsgraph has been evaluated. */ + wm_event_do_refresh_wm_and_depsgraph(C); + while (1) { /* get events from ghost, handle window events, add to window queues */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 25c6980f58e..2b695c95258 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -867,25 +867,13 @@ static bool wm_draw_update_test_window(wmWindow *win) static int wm_automatic_draw_method(wmWindow *win) { - /* Ideally all cards would work well with triple buffer, since if it works - * well gives the least redraws and is considerably faster at partial redraw - * for sculpting or drawing overlapping menus. For typically lower end cards - * copy to texture is slow though and so we use overlap instead there. */ - + /* We assume all supported GPUs now support triple buffer well. */ if (win->drawmethod == USER_DRAW_AUTOMATIC) { - /* Windows software driver darkens color on each redraw */ - if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_WIN, GPU_DRIVER_SOFTWARE)) - return USER_DRAW_OVERLAP_FLIP; - else if (GPU_type_matches(GPU_DEVICE_SOFTWARE, GPU_OS_UNIX, GPU_DRIVER_SOFTWARE)) - return USER_DRAW_OVERLAP; - /* drawing lower color depth again degrades colors each time */ - else if (GPU_color_depth() < 24) - return USER_DRAW_OVERLAP; - else - return USER_DRAW_TRIPLE; + return USER_DRAW_TRIPLE; } - else + else { return win->drawmethod; + } } bool WM_is_draw_triple(wmWindow *win) diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index f26ee0e73ec..7e7314cc0c8 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -263,13 +263,56 @@ static void wm_notifier_clear(wmNotifier *note) memset(((char *)note) + sizeof(Link), 0, sizeof(*note) - sizeof(Link)); } +/** + * Was part of #wm_event_do_notifiers, split out so it can be called once before entering the #WM_main loop. + * This ensures operators don't run before the UI and depsgraph are initialized. + */ +void wm_event_do_refresh_wm_and_depsgraph(bContext *C) +{ + wmWindowManager *wm = CTX_wm_manager(C); + uint64_t win_combine_v3d_datamask = 0; + + /* combine datamasks so 1 win doesn't disable UV's in another [#26448] */ + for (wmWindow *win = wm->windows.first; win; win = win->next) { + win_combine_v3d_datamask |= ED_view3d_screen_datamask(win->screen); + } + + /* cached: editor refresh callbacks now, they get context */ + for (wmWindow *win = wm->windows.first; win; win = win->next) { + ScrArea *sa; + + CTX_wm_window_set(C, win); + for (sa = win->screen->areabase.first; sa; sa = sa->next) { + if (sa->do_refresh) { + CTX_wm_area_set(C, sa); + ED_area_do_refresh(C, sa); + } + } + + /* XXX make lock in future, or separated derivedmesh users in scene */ + if (G.is_rendering == false) { + /* depsgraph & animation: update tagged datablocks */ + Main *bmain = CTX_data_main(C); + + /* copied to set's in scene_update_tagged_recursive() */ + win->screen->scene->customdata_mask = win_combine_v3d_datamask; + + /* XXX, hack so operators can enforce datamasks [#26482], gl render */ + win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal; + + BKE_scene_update_tagged(bmain->eval_ctx, bmain, win->screen->scene); + } + } + + CTX_wm_window_set(C, NULL); +} + /* called in mainloop */ void wm_event_do_notifiers(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmNotifier *note, *next; wmWindow *win; - uint64_t win_combine_v3d_datamask = 0; if (wm == NULL) return; @@ -373,39 +416,7 @@ void wm_event_do_notifiers(bContext *C) MEM_freeN(note); } - /* combine datamasks so 1 win doesn't disable UV's in another [#26448] */ - for (win = wm->windows.first; win; win = win->next) { - win_combine_v3d_datamask |= ED_view3d_screen_datamask(win->screen); - } - - /* cached: editor refresh callbacks now, they get context */ - for (win = wm->windows.first; win; win = win->next) { - ScrArea *sa; - - CTX_wm_window_set(C, win); - for (sa = win->screen->areabase.first; sa; sa = sa->next) { - if (sa->do_refresh) { - CTX_wm_area_set(C, sa); - ED_area_do_refresh(C, sa); - } - } - - /* XXX make lock in future, or separated derivedmesh users in scene */ - if (G.is_rendering == false) { - /* depsgraph & animation: update tagged datablocks */ - Main *bmain = CTX_data_main(C); - - /* copied to set's in scene_update_tagged_recursive() */ - win->screen->scene->customdata_mask = win_combine_v3d_datamask; - - /* XXX, hack so operators can enforce datamasks [#26482], gl render */ - win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal; - - BKE_scene_update_tagged(bmain->eval_ctx, bmain, win->screen->scene); - } - } - - CTX_wm_window_set(C, NULL); + wm_event_do_refresh_wm_and_depsgraph(C); } static int wm_event_always_pass(const wmEvent *event) @@ -615,6 +626,16 @@ bool WM_event_is_absolute(const wmEvent *event) return (event->tablet_data != NULL); } +bool WM_event_is_last_mousemove(const wmEvent *event) +{ + while ((event = event->next)) { + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { + return false; + } + } + return true; +} + #ifdef WITH_INPUT_NDOF void WM_ndof_deadzone_set(float deadzone) { @@ -1079,6 +1100,9 @@ bool WM_operator_last_properties_store(wmOperator *UNUSED(op)) #endif +/** + * Also used for exec when 'event' is NULL. + */ static int wm_operator_invoke( bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports, const bool poll_only) @@ -1094,7 +1118,9 @@ static int wm_operator_invoke( wmOperator *op = wm_operator_create(wm, ot, properties, reports); /* if reports == NULL, they'll be initialized */ const bool is_nested_call = (wm->op_undo_depth != 0); - op->flag |= OP_IS_INVOKE; + if (event != NULL) { + op->flag |= OP_IS_INVOKE; + } /* initialize setting from previous run */ if (!is_nested_call) { /* not called by py script */ @@ -2852,7 +2878,7 @@ void WM_event_add_mousemove(bContext *C) /* for modal callbacks, check configuration for how to interpret exit with tweaks */ -bool WM_modal_tweak_exit(const wmEvent *event, int tweak_event) +bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event) { /* if the release-confirm userpref setting is enabled, * tweak events can be canceled when mouse is released diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index b4a6366fb4e..637ace9cd82 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -449,7 +449,7 @@ void wm_file_read_report(bContext *C) * Logic shared between #WM_file_read & #wm_homefile_read, * updates to make after reading a file. */ -static void wm_file_read_post(bContext *C, bool is_startup_file) +static void wm_file_read_post(bContext *C, const bool is_startup_file, const bool use_userdef) { bool addons_loaded = false; wmWindowManager *wm = CTX_wm_manager(C); @@ -468,13 +468,14 @@ static void wm_file_read_post(bContext *C, bool is_startup_file) if (is_startup_file) { /* possible python hasn't been initialized */ if (CTX_py_init_get(C)) { - /* Only run when we have a template path found. */ - if (BKE_appdir_app_template_any()) { - BPY_execute_string(C, "__import__('bl_app_template_utils').reset()"); + if (use_userdef) { + /* Only run when we have a template path found. */ + if (BKE_appdir_app_template_any()) { + BPY_execute_string(C, "__import__('bl_app_template_utils').reset()"); + } + /* sync addons, these may have changed from the defaults */ + BPY_execute_string(C, "__import__('addon_utils').reset_all()"); } - /* sync addons, these may have changed from the defaults */ - BPY_execute_string(C, "__import__('addon_utils').reset_all()"); - BPY_python_reset(C); addons_loaded = true; } @@ -588,7 +589,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) } } - wm_file_read_post(C, false); + wm_file_read_post(C, false, false); success = true; } @@ -636,13 +637,15 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) * * \param use_factory_settings: Ignore on-disk startup file, use bundled ``datatoc_startup_blend`` instead. * Used for "Restore Factory Settings". + * \param use_userdef: Load factory settings as well as startup file. + * Disabled for "File New" we don't want to reload preferences. * \param filepath_startup_override: Optional path pointing to an alternative blend file (may be NULL). * \param app_template_override: Template to use instead of the template defined in user-preferences. * When not-null, this is written into the user preferences. */ int wm_homefile_read( bContext *C, ReportList *reports, - bool use_factory_settings, bool use_empty_data, + bool use_factory_settings, bool use_empty_data, bool use_userdef, const char *filepath_startup_override, const char *app_template_override) { ListBase wmbase; @@ -666,7 +669,7 @@ int wm_homefile_read( * And in this case versioning code is to be run. */ bool read_userdef_from_memory = false; - eBLOReadSkip skip_flags = 0; + eBLOReadSkip skip_flags = use_userdef ? 0 : BLO_READ_SKIP_USERDEF; /* options exclude eachother */ BLI_assert((use_factory_settings && filepath_startup_override) == 0); @@ -693,7 +696,9 @@ int wm_homefile_read( if (!use_factory_settings) { if (cfgdir) { BLI_path_join(filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE, NULL); - BLI_path_join(filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE, NULL); + if (use_userdef) { + BLI_path_join(filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE, NULL); + } } else { use_factory_settings = true; @@ -705,14 +710,16 @@ int wm_homefile_read( } /* load preferences before startup.blend */ - if (!use_factory_settings && BLI_exists(filepath_userdef)) { - UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL); - if (userdef != NULL) { - BKE_blender_userdef_set_data(userdef); - MEM_freeN(userdef); - - skip_flags |= BLO_READ_SKIP_USERDEF; - printf("Read prefs: %s\n", filepath_userdef); + if (use_userdef) { + if (!use_factory_settings && BLI_exists(filepath_userdef)) { + UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL); + if (userdef != NULL) { + BKE_blender_userdef_set_data(userdef); + MEM_freeN(userdef); + + skip_flags |= BLO_READ_SKIP_USERDEF; + printf("Read prefs: %s\n", filepath_userdef); + } } } @@ -721,23 +728,23 @@ int wm_homefile_read( if (filepath_startup_override != NULL) { /* pass */ } - else if (app_template_override && app_template_override[0]) { + else if (app_template_override) { + /* This may be clearing the current template by setting to an empty string. */ app_template = app_template_override; } else if (!use_factory_settings && U.app_template[0]) { app_template = U.app_template; } - if (app_template != NULL) { + if ((app_template != NULL) && (app_template[0] != '\0')) { BKE_appdir_app_template_id_search(app_template, app_template_system, sizeof(app_template_system)); - BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template, NULL); - } - /* insert template name into startup file */ - if (app_template != NULL) { + /* Insert template name into startup file. */ + /* note that the path is being set even when 'use_factory_settings == true' * this is done so we can load a templates factory-settings */ if (!use_factory_settings) { + BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template, NULL); BLI_path_join(filepath_startup, sizeof(filepath_startup), app_template_config, BLENDER_STARTUP_FILE, NULL); if (BLI_access(filepath_startup, R_OK) != 0) { filepath_startup[0] = '\0'; @@ -772,8 +779,12 @@ int wm_homefile_read( success = BKE_blendfile_read_from_memory( C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, skip_flags, true); - if (success && !(skip_flags & BLO_READ_SKIP_USERDEF)) { - read_userdef_from_memory = true; + if (success) { + if (use_userdef) { + if ((skip_flags & BLO_READ_SKIP_USERDEF) == 0) { + read_userdef_from_memory = true; + } + } } if (BLI_listbase_is_empty(&wmbase)) { wm_clear_default_size(C); @@ -801,21 +812,23 @@ int wm_homefile_read( BLI_path_join(temp_path, sizeof(temp_path), app_template_system, BLENDER_USERPREF_FILE, NULL); } - UserDef *userdef_template = NULL; - /* just avoids missing file warning */ - if (BLI_exists(temp_path)) { - userdef_template = BKE_blendfile_userdef_read(temp_path, NULL); - } - if (userdef_template == NULL) { - /* we need to have preferences load to overwrite preferences from previous template */ - userdef_template = BKE_blendfile_userdef_read_from_memory( - datatoc_startup_blend, datatoc_startup_blend_size, NULL); - read_userdef_from_memory = true; - } - if (userdef_template) { - BKE_blender_userdef_set_app_template(userdef_template); - BKE_blender_userdef_free_data(userdef_template); - MEM_freeN(userdef_template); + if (use_userdef) { + UserDef *userdef_template = NULL; + /* just avoids missing file warning */ + if (BLI_exists(temp_path)) { + userdef_template = BKE_blendfile_userdef_read(temp_path, NULL); + } + if (userdef_template == NULL) { + /* we need to have preferences load to overwrite preferences from previous template */ + userdef_template = BKE_blendfile_userdef_read_from_memory( + datatoc_startup_blend, datatoc_startup_blend_size, NULL); + read_userdef_from_memory = true; + } + if (userdef_template) { + BKE_blender_userdef_set_app_template(userdef_template); + BKE_blender_userdef_free_data(userdef_template); + MEM_freeN(userdef_template); + } } } @@ -827,8 +840,10 @@ int wm_homefile_read( * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; - /* check userdef before open window, keymaps etc */ - wm_init_userdef(C, read_userdef_from_memory); + if (use_userdef) { + /* check userdef before open window, keymaps etc */ + wm_init_userdef(C, read_userdef_from_memory); + } /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); @@ -836,9 +851,11 @@ int wm_homefile_read( G.main->name[0] = '\0'; - /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ - if (!G.background) { - GPU_default_lights(); + if (use_userdef) { + /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ + if (!G.background) { + GPU_default_lights(); + } } /* start with save preference untitled.blend */ @@ -846,7 +863,7 @@ int wm_homefile_read( /* disable auto-play in startup.blend... */ G.fileflags &= ~G_FILE_AUTOPLAY; - wm_file_read_post(C, true); + wm_file_read_post(C, true, use_userdef); return true; } @@ -1528,6 +1545,7 @@ void WM_OT_read_history(wmOperatorType *ot) static int wm_homefile_read_exec(bContext *C, wmOperator *op) { const bool use_factory_settings = (STREQ(op->type->idname, "WM_OT_read_factory_settings")); + bool use_userdef = false; char filepath_buf[FILE_MAX]; const char *filepath = NULL; @@ -1551,6 +1569,8 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op) else { /* always load UI for factory settings (prefs will re-init) */ G.fileflags &= ~G_FILE_NO_UI; + /* Always load preferences with factory settings. */ + use_userdef = true; } char app_template_buf[sizeof(U.app_template)]; @@ -1562,17 +1582,15 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op) if (prop_app_template && RNA_property_is_set(op->ptr, prop_app_template)) { RNA_property_string_get(op->ptr, prop_app_template, app_template_buf); app_template = app_template_buf; - } - else if (!use_factory_settings) { - /* TODO: dont reset prefs on 'New File' */ - BLI_strncpy(app_template_buf, U.app_template, sizeof(app_template_buf)); - app_template = app_template_buf; + + /* Always load preferences when switching templates. */ + use_userdef = true; } else { app_template = NULL; } - if (wm_homefile_read(C, op->reports, use_factory_settings, use_empty_data, filepath, app_template)) { + if (wm_homefile_read(C, op->reports, use_factory_settings, use_empty_data, use_userdef, filepath, app_template)) { if (use_splash) { WM_init_splash(C); } diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index 46203333eb5..e04571fe572 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -137,7 +137,7 @@ int wm_gesture_evaluate(wmGesture *gesture) int dx = BLI_rcti_size_x(rect); int dy = BLI_rcti_size_y(rect); if (abs(dx) + abs(dy) > U.tweak_threshold) { - int theta = iroundf(4.0f * atan2f((float)dy, (float)dx) / (float)M_PI); + int theta = round_fl_to_int(4.0f * atan2f((float)dy, (float)dx) / (float)M_PI); int val = EVT_GESTURE_W; if (theta == 0) val = EVT_GESTURE_E; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 00a9976e8be..e73ec2b081a 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -184,15 +184,12 @@ void WM_init(bContext *C, int argc, const char **argv) BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ BLT_lang_init(); - /* Enforce loading the UI for the initial homefile */ - G.fileflags &= ~G_FILE_NO_UI; - /* reports cant be initialized before the wm, * but keep before file reading, since that may report errors */ wm_init_reports(C); /* get the default database, plus a wm */ - wm_homefile_read(C, NULL, G.factory_startup, false, NULL, NULL); + wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, NULL); BLT_lang_set(NULL); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index d3ebd3e4d2c..51c551cd9a5 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -177,7 +177,7 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType *)) /* XXX All ops should have a description but for now allow them not to. */ RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP); - RNA_def_struct_identifier(ot->srna, ot->idname); + RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname); BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot); } @@ -193,7 +193,7 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *, void *), void * ot->translation_context = BLT_I18NCONTEXT_OPERATOR_DEFAULT; opfunc(ot, userdata); RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP); - RNA_def_struct_identifier(ot->srna, ot->idname); + RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname); BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot); } @@ -398,7 +398,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam ot->description = UNDOCUMENTED_OPERATOR_TIP; RNA_def_struct_ui_text(ot->srna, ot->name, ot->description); - RNA_def_struct_identifier(ot->srna, ot->idname); + RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname); /* Use i18n context from ext.srna if possible (py operators). */ i18n_context = ot->ext.srna ? RNA_struct_translation_context(ot->ext.srna) : BLT_I18NCONTEXT_OPERATOR_DEFAULT; RNA_def_struct_translation_context(ot->srna, i18n_context); @@ -432,7 +432,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *), opfunc(ot, userdata); RNA_def_struct_ui_text(ot->srna, ot->name, ot->description); - RNA_def_struct_identifier(ot->srna, ot->idname); + RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname); BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot); } @@ -573,6 +573,46 @@ void WM_operator_bl_idname(char *to, const char *from) } /** + * Sanity check to ensure #WM_operator_bl_idname won't fail. + * \returns true when there are no problems with \a idname, otherwise report an error. + */ +bool WM_operator_py_idname_ok_or_report(ReportList *reports, const char *classname, const char *idname) +{ + const char *ch = idname; + int dot = 0; + int i; + for (i = 0; *ch; i++, ch++) { + if ((*ch >= 'a' && *ch <= 'z') || (*ch >= '0' && *ch <= '9') || *ch == '_') { + /* pass */ + } + else if (*ch == '.') { + dot++; + } + else { + BKE_reportf(reports, RPT_ERROR, + "Registering operator class: '%s', invalid bl_idname '%s', at position %d", + classname, idname, i); + return false; + } + } + + if (i > (MAX_NAME - 3)) { + BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', " + "is too long, maximum length is %d", classname, idname, + MAX_NAME - 3); + return false; + } + + if (dot != 1) { + BKE_reportf(reports, RPT_ERROR, + "Registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", + classname, idname); + return false; + } + return true; +} + +/** * Print a string representation of the operator, with the args that it runs so python can run it again. * * When calling from an existing wmOperator, better to use simple version: @@ -806,9 +846,19 @@ static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, Propert } \ } (void)0 +#define CTX_TEST_SPACE_TYPE(space_data_type, member_full, dataptr_cmp) \ + { \ + const char *ctx_member_full = member_full; \ + if (space_data->spacetype == space_data_type && ptr->data == dataptr_cmp) { \ + member_id = ctx_member_full; \ + break; \ + } \ + } (void)0 + switch (GS(((ID *)ptr->id.data)->name)) { case ID_SCE: { + CTX_TEST_PTR_DATA_TYPE(C, "active_gpencil_brush", RNA_GPencilBrush, ptr, CTX_data_active_gpencil_brush(C)); CTX_TEST_PTR_ID(C, "scene", ptr->id.data); break; } @@ -843,12 +893,22 @@ static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, Propert { CTX_TEST_PTR_ID(C, "screen", ptr->id.data); - CTX_TEST_PTR_DATA_TYPE(C, "space_data", RNA_Space, ptr, CTX_wm_space_data(C)); + SpaceLink *space_data = CTX_wm_space_data(C); + + CTX_TEST_PTR_DATA_TYPE(C, "space_data", RNA_Space, ptr, space_data); CTX_TEST_PTR_DATA_TYPE(C, "area", RNA_Area, ptr, CTX_wm_area(C)); CTX_TEST_PTR_DATA_TYPE(C, "region", RNA_Region, ptr, CTX_wm_region(C)); + CTX_TEST_SPACE_TYPE(SPACE_IMAGE, "space_data.uv_editor", space_data); + CTX_TEST_SPACE_TYPE(SPACE_VIEW3D, "space_data.fx_settings", &(CTX_wm_view3d(C)->fx_settings)); + CTX_TEST_SPACE_TYPE(SPACE_NLA, "space_data.dopesheet", CTX_wm_space_nla(C)->ads); + CTX_TEST_SPACE_TYPE(SPACE_IPO, "space_data.dopesheet", CTX_wm_space_graph(C)->ads); + CTX_TEST_SPACE_TYPE(SPACE_ACTION, "space_data.dopesheet", &(CTX_wm_space_action(C)->ads)); + CTX_TEST_SPACE_TYPE(SPACE_FILE, "space_data.params", CTX_wm_space_file(C)->params); break; } + default: + break; } if (member_id) { @@ -860,6 +920,7 @@ static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, Propert } #undef CTX_TEST_PTR_ID #undef CTX_TEST_PTR_ID_CAST +#undef CTX_TEST_SPACE_TYPE } return ret; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 8afeb8e7b3d..9fe215f7712 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -377,7 +377,12 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) void WM_window_set_dpi(wmWindow *win) { - int auto_dpi = GHOST_GetDPIHint(win->ghostwin); + float auto_dpi = GHOST_GetDPIHint(win->ghostwin); + + /* Clamp auto DPI to 96, since our font/interface drawing does not work well + * with lower sizes. The main case we are interested in supporting is higher + * DPI. If a smaller UI is desired it is still possible to adjust UI scale. */ + auto_dpi = max_ff(auto_dpi, 96.0f); /* Lazily init UI scale size, preserving backwards compatibility by * computing UI scale from ratio of previous DPI and auto DPI */ @@ -397,13 +402,16 @@ void WM_window_set_dpi(wmWindow *win) /* Blender's UI drawing assumes DPI 72 as a good default following macOS * while Windows and Linux use DPI 96. GHOST assumes a default 96 so we * remap the DPI to Blender's convention. */ + auto_dpi *= GHOST_GetNativePixelSize(win->ghostwin); int dpi = auto_dpi * U.ui_scale * (72.0 / 96.0f); /* Automatically set larger pixel size for high DPI. */ - int pixelsize = MAX2(1, dpi / 54); + int pixelsize = max_ii(1, (int)(dpi / 64)); + /* User adjustment for pixel size. */ + pixelsize = max_ii(1, pixelsize + U.ui_line_width); /* Set user preferences globals for drawing, and for forward compatibility. */ - U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin) * pixelsize; + U.pixelsize = pixelsize; U.dpi = dpi / pixelsize; U.virtual_pixel = (pixelsize == 1) ? VIRTUAL_PIXEL_NATIVE : VIRTUAL_PIXEL_DOUBLE; U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72; |