Blender V4.5
buttons_ops.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "DNA_userdef_types.h"
15
16#include "BLI_fileops.h"
17#include "BLI_path_utils.hh"
18#include "BLI_string.h"
19#include "BLI_utildefines.h"
20
21#include "BLT_translation.hh"
22
23#include "BKE_appdir.hh"
24#include "BKE_context.hh"
25#include "BKE_library.hh"
26#include "BKE_main.hh"
27#include "BKE_path_templates.hh"
28#include "BKE_report.hh"
29#include "BKE_screen.hh"
30
31#include "WM_api.hh"
32#include "WM_types.hh"
33
34#include "ED_screen.hh"
35#include "ED_undo.hh"
36
37#include "RNA_access.hh"
38#include "RNA_define.hh"
39#include "RNA_prototypes.hh"
40
41#include "UI_interface.hh"
42#include "UI_resources.hh"
43
44#include "buttons_intern.hh" /* own include */
45
46/* -------------------------------------------------------------------- */
51
53{
55 ScrArea *area = CTX_wm_area(C);
57
58 UI_textbutton_activate_rna(C, region, space, "search_filter");
59
60 return OPERATOR_FINISHED;
61}
62
64{
65 /* Identifiers. */
66 ot->name = "Filter";
67 ot->description = "Start entering filter text";
68 ot->idname = "BUTTONS_OT_start_filter";
69
70 /* Callbacks. */
73}
74
87
89{
90 /* Identifiers. */
91 ot->name = "Clear Filter";
92 ot->description = "Clear the search filter";
93 ot->idname = "BUTTONS_OT_clear_filter";
94
95 /* Callbacks. */
98}
99
101
102/* -------------------------------------------------------------------- */
105
107{
109
110 sbuts->flag ^= SB_PIN_CONTEXT;
111
112 /* Create the properties space pointer. */
113 bScreen *screen = CTX_wm_screen(C);
114 PointerRNA sbuts_ptr = RNA_pointer_create_discrete(&screen->id, &RNA_SpaceProperties, sbuts);
115
116 /* Create the new ID pointer and set the pin ID with RNA
117 * so we can use the property's RNA update functionality. */
118 ID *new_id = (sbuts->flag & SB_PIN_CONTEXT) ? buttons_context_id_path(C) : nullptr;
119 PointerRNA new_id_ptr = RNA_id_pointer_create(new_id);
120 RNA_pointer_set(&sbuts_ptr, "pin_id", new_id_ptr);
121
123
124 return OPERATOR_FINISHED;
125}
126
128{
129 /* Identifiers. */
130 ot->name = "Toggle Pin ID";
131 ot->description = "Keep the current data-block displayed";
132 ot->idname = "BUTTONS_OT_toggle_pin";
133
134 /* Callbacks. */
135 ot->exec = toggle_pin_exec;
137}
138
140
141/* -------------------------------------------------------------------- */
144
146 wmOperator * /*op*/,
147 const wmEvent * /*event*/)
148{
149 uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Context Menu"), ICON_NONE);
150 uiLayout *layout = UI_popup_menu_layout(pup);
151
152 layout->menu("INFO_MT_area", std::nullopt, ICON_NONE);
153 UI_popup_menu_end(C, pup);
154
155 return OPERATOR_INTERFACE;
156}
157
159{
160 /* Identifiers. */
161 ot->name = "Context Menu";
162 ot->description = "Display properties editor context_menu";
163 ot->idname = "BUTTONS_OT_context_menu";
164
165 /* Callbacks. */
166 ot->invoke = context_menu_invoke;
168}
169
171
172/* -------------------------------------------------------------------- */
175
178 PropertyRNA *prop = nullptr;
179 bool is_undo = false;
180 bool is_userdef = false;
181};
182
184{
185 FileBrowseOp *fbo = static_cast<FileBrowseOp *>(op->customdata);
186 const PropertySubType subtype = RNA_property_subtype(fbo->prop);
187 if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH)) {
188 const int flag = RNA_property_flag(fbo->prop);
190 return false;
191 }
192 }
193 return true;
194}
195
197{
198 Main *bmain = CTX_data_main(C);
199 FileBrowseOp *fbo = static_cast<FileBrowseOp *>(op->customdata);
200 char *path;
201 const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" :
202 "filepath";
203
204 if (fbo == nullptr) {
205 return OPERATOR_CANCELLED;
206 }
207 if (RNA_struct_property_is_set(op->ptr, path_prop) == 0) {
208 MEM_delete(fbo);
209 return OPERATOR_CANCELLED;
210 }
211
212 path = RNA_string_get_alloc(op->ptr, path_prop, nullptr, 0, nullptr);
213
214 if (path[0]) {
215 /* Check relative paths are supported here as this option will be hidden
216 * when it's not supported. In this case the value may have been enabled
217 * by default or from the last-used setting.
218 * Either way, don't use the blend-file relative prefix when it's not supported. */
219 const PropertySubType prop_subtype = RNA_property_subtype(fbo->prop);
220 const bool is_relative = BLI_path_is_rel(path);
221 const bool make_relative = RNA_boolean_get(op->ptr, "relative_path") &&
223
224 /* Add slash for directories, important for some properties. */
225 if ((prop_subtype == PROP_DIRPATH) || (is_relative || make_relative)) {
226 char path_buf[FILE_MAX];
227 ID *id = fbo->ptr.owner_id;
228
229 STRNCPY(path_buf, path);
230 MEM_freeN(path);
231
232 if (is_relative) {
233 BLI_path_abs(path_buf, id ? ID_BLEND_PATH(bmain, id) : BKE_main_blendfile_path(bmain));
234 }
235
236 if (prop_subtype == PROP_DIRPATH) {
237 BLI_path_slash_ensure(path_buf, sizeof(path_buf));
238 }
239
240 if (make_relative) {
241 BLI_path_rel(path_buf, BKE_main_blendfile_path(bmain));
242 }
243 path = BLI_strdup(path_buf);
244 }
245 }
246
247 RNA_property_string_set(&fbo->ptr, fbo->prop, path);
248 RNA_property_update(C, &fbo->ptr, fbo->prop);
249 MEM_freeN(path);
250
251 if (fbo->is_undo) {
252 const char *undostr = RNA_property_identifier(fbo->prop);
253 ED_undo_push(C, undostr);
254 }
255
256 /* Special annoying exception, filesel on redo panel #26618. */
257 {
259 if (redo_op) {
260 if (fbo->ptr.data == redo_op->ptr->data) {
261 ED_undo_operator_repeat(C, redo_op);
262 }
263 }
264 }
265
266 /* Tag user preferences as dirty. */
267 if (fbo->is_userdef) {
268 U.runtime.is_dirty = true;
269 }
270
271 BLI_assert(fbo == op->customdata);
272 MEM_delete(fbo);
273
274 return OPERATOR_FINISHED;
275}
276
277static void file_browse_cancel(bContext * /*C*/, wmOperator *op)
278{
279 FileBrowseOp *fbo = static_cast<FileBrowseOp *>(op->customdata);
280 MEM_delete(fbo);
281 op->customdata = nullptr;
282}
283
285{
287 PropertyRNA *prop;
288 bool is_undo;
289 bool is_userdef;
290 char *path;
291
292 const SpaceFile *sfile = CTX_wm_space_file(C);
293 if (sfile && sfile->op) {
294 BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector dialog, one already open");
295 return OPERATOR_CANCELLED;
296 }
297
298 UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop, &is_undo, &is_userdef);
299
300 if (!prop) {
301 return OPERATOR_CANCELLED;
302 }
303
304 path = RNA_property_string_get_alloc(&ptr, prop, nullptr, 0, nullptr);
305
307 const std::optional<blender::bke::path_templates::VariableMap> variables =
309 BLI_assert(variables.has_value());
310
312 path, FILE_MAX, *variables);
313 if (!errors.is_empty()) {
315 return OPERATOR_CANCELLED;
316 }
317 }
318
319 /* Useful yet irritating feature, Shift+Click to open the file
320 * Alt+Click to browse a folder in the OS's browser. */
321 if (event->modifier & (KM_SHIFT | KM_ALT)) {
322 wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
323 PointerRNA props_ptr;
324
325 if (event->modifier & KM_ALT) {
326 char *lslash = (char *)BLI_path_slash_rfind(path);
327 if (lslash) {
328 *lslash = '\0';
329 }
330 }
331
333 RNA_string_set(&props_ptr, "filepath", path);
334 WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr, nullptr);
335 WM_operator_properties_free(&props_ptr);
336
337 MEM_freeN(path);
338 return OPERATOR_CANCELLED;
339 }
340
341 {
342 const char *info;
343 if (!RNA_property_editable_info(&ptr, prop, &info)) {
344 if (info[0]) {
345 BKE_reportf(op->reports, RPT_ERROR, "Property is not editable: %s", info);
346 }
347 else {
348 BKE_report(op->reports, RPT_ERROR, "Property is not editable");
349 }
350 MEM_freeN(path);
351 return OPERATOR_CANCELLED;
352 }
353 }
354
355 PropertyRNA *prop_relpath;
356 const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" :
357 "filepath";
358 FileBrowseOp *fbo = MEM_new<FileBrowseOp>(__func__);
359 fbo->ptr = ptr;
360 fbo->prop = prop;
361 fbo->is_undo = is_undo;
362 fbo->is_userdef = is_userdef;
363
364 op->customdata = fbo;
365
366 /* NOTE(@ideasman42): Normally #ED_fileselect_get_params would handle this
367 * but we need to because of stupid user-preferences exception. */
368 if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
369 if (!RNA_property_is_set(op->ptr, prop_relpath)) {
370 bool is_relative = (U.flag & USER_RELPATHS) != 0;
371
372 /* While we want to follow the defaults,
373 * we better not switch existing paths relative/absolute state. */
374 if (path[0]) {
375 is_relative = BLI_path_is_rel(path);
376 }
377
378 if (UNLIKELY(ptr.data == &U || is_userdef)) {
379 is_relative = false;
380 }
381
382 /* Annoying exception!, if we're dealing with the user preferences,
383 * default relative to be off. */
384 RNA_property_boolean_set(op->ptr, prop_relpath, is_relative);
385 }
386 }
387
388 const char *prop_id = RNA_property_identifier(prop);
389
390 /* NOTE: relying on built-in names isn't useful for add-on authors.
391 * The property itself should support this kind of meta-data. */
392 if (STR_ELEM(prop_id, "font_path_ui", "font_path_ui_mono", "font_directory")) {
393 RNA_boolean_set(op->ptr, "filter_font", true);
394 RNA_boolean_set(op->ptr, "filter_folder", true);
395 RNA_enum_set(op->ptr, "display_type", FILE_IMGDISPLAY);
396 RNA_enum_set(op->ptr, "sort_method", FILE_SORT_ALPHA);
397 if (!path[0]) {
398 char fonts_path[FILE_MAX] = {0};
399 if (U.fontdir[0]) {
400 STRNCPY(fonts_path, U.fontdir);
401 /* The file selector will expand the blend-file relative prefix. */
402 }
403 else if (!BKE_appdir_font_folder_default(fonts_path, ARRAY_SIZE(fonts_path))) {
405 }
406 BLI_path_slash_ensure(fonts_path, ARRAY_SIZE(fonts_path));
407 MEM_freeN(path);
408 path = BLI_strdup(fonts_path);
409 }
410 }
411
412 if (!path[0]) {
413 /* Find a reasonable folder to start in if none found. */
414 char default_path[FILE_MAX] = {0};
416 BLI_path_slash_ensure(default_path, ARRAY_SIZE(default_path));
417 MEM_freeN(path);
418 path = BLI_strdup(default_path);
419 }
420
421 RNA_string_set(op->ptr, path_prop, path);
422 MEM_freeN(path);
423
424 PropertyRNA *prop_check_existing = RNA_struct_find_property(op->ptr, "check_existing");
425 if (!RNA_property_is_set(op->ptr, prop_check_existing)) {
426 const bool is_output_path = (RNA_property_flag(prop) & PROP_PATH_OUTPUT) != 0;
427 RNA_property_boolean_set(op->ptr, prop_check_existing, is_output_path);
428 }
429 if (std::optional<std::string> filter = RNA_property_string_path_filter(C, &ptr, prop)) {
430 RNA_string_set(op->ptr, "filter_glob", filter->c_str());
431 }
432
434
436}
437
438static bool file_browse_poll_property(const bContext * /*C*/,
439 wmOperator *op,
440 const PropertyRNA *prop)
441{
442 const char *prop_id = RNA_property_identifier(prop);
443 if (STREQ(prop_id, "relative_path")) {
445 return false;
446 }
447 }
448 return true;
449}
450
452{
453 /* Identifiers. */
454 ot->name = "Accept";
455 ot->description =
456 "Open a file browser, hold Shift to open the file, Alt to browse containing directory";
457 ot->idname = "BUTTONS_OT_file_browse";
458
459 /* Callbacks. */
460 ot->invoke = file_browse_invoke;
461 ot->exec = file_browse_exec;
462 ot->cancel = file_browse_cancel;
463 ot->poll_property = file_browse_poll_property;
464
465 /* Conditional undo based on button flag. */
466 ot->flag = 0;
467
468 /* Properties. */
470 0,
476
477 PropertyRNA *prop;
478
479 prop = RNA_def_string(ot->srna, "filter_glob", nullptr, 0, "Glob Filter", "Custom filter");
481}
482
484{
485 /* identifiers */
486 ot->name = "Accept";
487 ot->description =
488 "Open a directory browser, hold Shift to open the file, Alt to browse containing directory";
489 ot->idname = "BUTTONS_OT_directory_browse";
490
491 /* API callbacks. */
492 ot->invoke = file_browse_invoke;
493 ot->exec = file_browse_exec;
494 ot->cancel = file_browse_cancel;
495 ot->poll_property = file_browse_poll_property;
496
497 /* conditional undo based on button flag */
498 ot->flag = 0;
499
500 /* properties */
502 0,
508}
509
const char * BKE_appdir_folder_default_or_root() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition appdir.cc:163
bool BKE_appdir_font_folder_default(char *dir, size_t dir_maxncpy)
Definition appdir.cc:226
bScreen * CTX_wm_screen(const bContext *C)
SpaceFile * CTX_wm_space_file(const bContext *C)
SpaceProperties * CTX_wm_space_properties(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:877
Functions and classes for applying templates with variable expressions to filepaths.
void BKE_report_path_template_errors(ReportList *reports, eReportType report_type, blender::StringRef path, blender::Span< blender::bke::path_templates::Error > errors)
std::optional< blender::bke::path_templates::VariableMap > BKE_build_template_variables_for_prop(const bContext *C, PointerRNA *ptr, PropertyRNA *prop)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
ARegion * BKE_area_find_region_type(const ScrArea *area, int region_type)
Definition screen.cc:840
#define BLI_assert(a)
Definition BLI_assert.h:46
File and directory operations.
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define FILE_MAX
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
bool void BLI_path_rel(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1)
int BLI_path_slash_ensure(char *path, size_t path_maxncpy) ATTR_NONNULL(1)
const char * BLI_path_slash_rfind(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
#define STR_ELEM(...)
Definition BLI_string.h:656
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
#define ARRAY_SIZE(arr)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define IFACE_(msgid)
@ RGN_TYPE_HEADER
@ FILE_SORT_DEFAULT
@ FILE_SORT_ALPHA
@ FILE_SPECIAL
@ SB_PIN_CONTEXT
@ FILE_IMGDISPLAY
@ FILE_DEFAULTDISPLAY
@ USER_RELPATHS
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:714
void ED_region_search_filter_update(const ScrArea *area, ARegion *region)
Definition area.cc:859
bool ED_operator_buttons_active(bContext *C)
void ED_undo_push(bContext *C, const char *str)
Definition ed_undo.cc:99
bool ED_undo_operator_repeat(bContext *C, wmOperator *op)
Definition ed_undo.cc:630
Read Guarded memory(de)allocation.
@ PROP_PATH_OUTPUT
Definition RNA_types.hh:425
@ PROP_PATH_SUPPORTS_BLEND_RELATIVE
Definition RNA_types.hh:430
@ PROP_PATH_SUPPORTS_TEMPLATES
Definition RNA_types.hh:443
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
@ PROP_HIDDEN
Definition RNA_types.hh:324
PropertySubType
Definition RNA_types.hh:220
@ PROP_DIRPATH
Definition RNA_types.hh:225
@ PROP_FILEPATH
Definition RNA_types.hh:224
#define C
Definition RandGen.cpp:29
bool UI_textbutton_activate_rna(const bContext *C, ARegion *region, const void *rna_poin_data, const char *rna_prop_id)
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
void UI_context_active_but_prop_get_filebrowser(const bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop, bool *r_is_undo, bool *r_is_userdef)
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
@ WM_FILESEL_DIRECTORY
Definition WM_api.hh:1073
@ WM_FILESEL_RELPATH
Definition WM_api.hh:1072
@ WM_FILESEL_FILEPATH
Definition WM_api.hh:1075
@ FILE_OPENFILE
Definition WM_api.hh:1084
@ KM_ALT
Definition WM_types.hh:277
@ KM_SHIFT
Definition WM_types.hh:275
@ WM_OP_EXEC_DEFAULT
Definition WM_types.hh:245
#define U
ID * buttons_context_id_path(const bContext *C)
static wmOperatorStatus file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void file_browse_cancel(bContext *, wmOperator *op)
static wmOperatorStatus context_menu_invoke(bContext *C, wmOperator *, const wmEvent *)
void BUTTONS_OT_toggle_pin(wmOperatorType *ot)
void BUTTONS_OT_context_menu(wmOperatorType *ot)
void BUTTONS_OT_directory_browse(wmOperatorType *ot)
static wmOperatorStatus buttons_start_filter_exec(bContext *C, wmOperator *)
static wmOperatorStatus buttons_clear_filter_exec(bContext *C, wmOperator *)
static bool file_browse_operator_relative_paths_supported(wmOperator *op)
static wmOperatorStatus file_browse_exec(bContext *C, wmOperator *op)
static wmOperatorStatus toggle_pin_exec(bContext *C, wmOperator *)
void BUTTONS_OT_clear_filter(wmOperatorType *ot)
static bool file_browse_poll_property(const bContext *, wmOperator *op, const PropertyRNA *prop)
void BUTTONS_OT_file_browse(wmOperatorType *ot)
void BUTTONS_OT_start_filter(wmOperatorType *ot)
bool is_empty() const
#define filter
#define ID_BLEND_PATH(_bmain, _id)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
blender::Vector< Error > BKE_path_apply_template(char *path, int path_max_length, const VariableMap &template_variables)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
std::optional< std::string > RNA_property_string_path_filter(const bContext *C, PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_flag(PropertyRNA *prop)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
bool RNA_property_editable_info(const PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const char * RNA_property_identifier(const PropertyRNA *prop)
PointerRNA RNA_id_pointer_create(ID *id)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PointerRNA ptr
PropertyRNA * prop
Definition DNA_ID.h:404
ID * owner_id
Definition RNA_types.hh:51
void * data
Definition RNA_types.hh:53
struct wmOperator * op
char search_string[UI_MAX_NAME_STR]
struct SpaceProperties_Runtime * runtime
void menu(MenuType *mt, std::optional< blender::StringRef > name, int icon)
wmEventModifierFlag modifier
Definition WM_types.hh:771
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_fileselect(bContext *C, wmOperator *op)
wmOperatorStatus WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
PointerRNA * ptr
Definition wm_files.cc:4227
wmOperatorType * ot
Definition wm_files.cc:4226
void WM_operator_properties_filesel(wmOperatorType *ot, const int filter, const short type, const eFileSel_Action action, const eFileSel_Flag flag, const short display, const short sort)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
wmOperator * WM_operator_last_redo(const bContext *C)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_operator_properties_free(PointerRNA *ptr)
uint8_t flag
Definition wm_window.cc:139