[Bf-blender-cvs] [db07bce] workspaces: Fix crash when toggling area fullscreen
Julian Eisel
noreply at git.blender.org
Tue Dec 6 02:42:44 CET 2016
Commit: db07bce54fbf681a0259e898ede1f16bf8a3d021
Author: Julian Eisel
Date: Tue Dec 6 02:42:05 2016 +0100
Branches: workspaces
https://developer.blender.org/rBdb07bce54fbf681a0259e898ede1f16bf8a3d021
Fix crash when toggling area fullscreen
===================================================================
M source/blender/blenkernel/BKE_workspace.h
M source/blender/blenkernel/intern/workspace.c
M source/blender/editors/include/ED_screen.h
M source/blender/editors/screen/screen_edit.c
M source/blender/editors/screen/screen_ops.c
M source/blender/editors/screen/workspace_edit.c
M source/blender/windowmanager/intern/wm_event_system.c
M source/blender/windowmanager/intern/wm_window.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 96ef529..0529297 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -39,6 +39,7 @@ struct WorkSpace *BKE_workspace_duplicate(Main *bmain, const struct WorkSpace *f
void BKE_workspace_free(struct WorkSpace *ws);
struct WorkSpaceLayout *BKE_workspace_layout_add(struct WorkSpace *workspace, struct bScreen *screen) ATTR_NONNULL();
+void BKE_workspace_layout_remove(struct WorkSpace *workspace, struct WorkSpaceLayout *layout) ATTR_NONNULL();
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 176e2da..933b77a 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -82,6 +82,12 @@ WorkSpaceLayout *BKE_workspace_layout_add(WorkSpace *workspace, bScreen *screen)
return layout;
}
+void BKE_workspace_layout_remove(WorkSpace *workspace, WorkSpaceLayout *layout)
+{
+ BLI_remlink(&workspace->layouts, layout);
+ MEM_freeN(layout);
+}
+
/* -------------------------------------------------------------------- */
/* General Utils */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 0297e5e..a2c1ef7 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -105,7 +105,7 @@ void ED_screen_draw(struct wmWindow *win);
void ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
void ED_screen_do_listen(struct bContext *C, struct wmNotifier *note);
bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc, WorkSpaceLayout **r_layout);
-bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, const char *name);
+bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, const char *name, WorkSpaceLayout **r_layout);
bool ED_screen_set(struct bContext *C, struct bScreen *sc);
bool ED_screen_delete(struct bContext *C, struct bScreen *sc);
void ED_screen_set_scene(struct bContext *C, struct bScreen *screen, struct Scene *scene);
@@ -127,7 +127,7 @@ void ED_screen_preview_render(const struct bScreen *screen, int size_x, int s
bool ED_workspace_change(struct bContext *C, struct wmWindow *win, WorkSpace *ws_new) ATTR_NONNULL();
WorkSpace *ED_workspace_duplicate(struct Main *bmain, struct wmWindow *win);
bool ED_workspace_delete(struct Main *bmain, struct bContext *C, struct wmWindow *win, WorkSpace *ws);
-bool ED_workspace_layout_circle(struct bContext *C, struct wmWindow *win, const short direction) ATTR_NONNULL();
+bool ED_workspace_layout_cycle(struct bContext *C, struct wmWindow *win, const short direction) ATTR_NONNULL();
/* anim */
void ED_update_for_newframe(struct Main *bmain, struct Scene *scene, int mute);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 8b8642b..34df34d 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -459,9 +459,11 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge)
return newa;
}
-/* empty screen, with 1 dummy area without spacedata */
-/* uses window size */
-bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name)
+/**
+ * Empty screen, with 1 dummy area without spacedata. Uses window size.
+ * \param r_layout: The layout wrapper created for \a sc. Can be NULL to skip layout creation.
+ */
+bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name, WorkSpaceLayout **r_layout)
{
const int winsize_x = WM_window_pixels_x(win);
const int winsize_y = WM_window_pixels_y(win);
@@ -487,7 +489,11 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name)
/* dummy type, no spacedata */
screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_EMPTY);
-
+
+ if (r_layout) {
+ *r_layout = BKE_workspace_layout_add(win->workspace, sc);
+ }
+
return sc;
}
@@ -1062,14 +1068,10 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc, WorkSpaceLayout **r_lay
if (sc->state != SCREENNORMAL) return NULL; /* XXX handle this case! */
/* make new empty screen: */
- newsc = ED_screen_add(win, sc->scene, sc->id.name + 2);
+ newsc = ED_screen_add(win, sc->scene, sc->id.name + 2, r_layout);
/* copy all data */
screen_copy(newsc, sc);
- if (r_layout) {
- *r_layout = BKE_workspace_layout_add(win->workspace, newsc);
- }
-
return newsc;
}
@@ -1954,6 +1956,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
}
if (sa && sa->full) {
+ WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
/* restoring back to SCREENNORMAL */
ScrArea *old;
@@ -1988,6 +1991,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
ED_screen_set(C, sc);
+ BKE_workspace_layout_remove(win->workspace, layout_old);
BKE_screen_free(oldscreen);
BKE_libblock_free(CTX_data_main(C), oldscreen);
@@ -1999,6 +2003,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
}
else {
/* change from SCREENNORMAL to new state */
+ WorkSpaceLayout *layout_new;
ScrArea *newa;
char newname[MAX_ID_NAME - 2];
@@ -2006,7 +2011,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
oldscreen->state = state;
BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal");
- sc = ED_screen_add(win, oldscreen->scene, newname);
+ sc = ED_screen_add(win, oldscreen->scene, newname, &layout_new);
sc->state = state;
sc->redraws_flag = oldscreen->redraws_flag;
sc->temp = oldscreen->temp;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 15f8719..343557e 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -980,6 +980,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *newwin, *win;
+ WorkSpaceLayout *layout;
bScreen *newsc, *sc;
ScrArea *sa;
rcti rect;
@@ -1014,8 +1015,8 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
newwin->workspace = win->workspace;
/* allocs new screen and adds to newly created window, using window size */
- newsc = ED_screen_add(newwin, CTX_data_scene(C), sc->id.name + 2);
- WM_window_set_active_screen(newwin, newsc);
+ newsc = ED_screen_add(newwin, CTX_data_scene(C), sc->id.name + 2, &layout);
+ WM_window_set_active_layout(newwin, layout);
/* copy area to new screen */
ED_area_data_copy((ScrArea *)newsc->areabase.first, sa, true);
@@ -2392,7 +2393,7 @@ static int screen_set_exec(bContext *C, wmOperator *op)
wmWindow *win = CTX_wm_window(C);
int delta = RNA_int_get(op->ptr, "delta");
- if (ED_workspace_layout_circle(C, win, delta)) {
+ if (ED_workspace_layout_cycle(C, win, delta)) {
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index ba8085b..cf9e48a 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -121,7 +121,7 @@ static bool workspace_layout_set_poll(const WorkSpaceLayout *layout)
(screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT)));
}
-bool ED_workspace_layout_circle(bContext *C, wmWindow *win, const short direction)
+bool ED_workspace_layout_cycle(bContext *C, wmWindow *win, const short direction)
{
const WorkSpace *workspace = win->workspace;
WorkSpaceLayout *old_layout = WM_window_get_active_layout(win);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 16fce26..13e0b73 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2479,6 +2479,9 @@ void wm_event_do_handlers(bContext *C)
while ( (event = win->queue.first) ) {
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)) {
printf("\n%s: Handling event\n", __func__);
WM_event_print(event);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 9adee49..a1172e5 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -661,9 +661,10 @@ wmWindow *WM_window_open_temp(bContext *C, const rcti *rect_init, int type)
}
if (screen == NULL) {
- screen = ED_screen_add(win, scene, "temp");
/* add new screen */
- WM_window_set_active_screen(win, screen);
+ WorkSpaceLayout *layout;
+ screen = ED_screen_add(win, scene, "temp", &layout);
+ WM_window_set_active_layout(win, layout);
}
else {
/* switch scene for rendering */
More information about the Bf-blender-cvs
mailing list