From the todo:
authorTon Roosendaal <ton@blender.org>
Wed, 9 Mar 2011 18:42:35 +0000 (18:42 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 9 Mar 2011 18:42:35 +0000 (18:42 +0000)
Hanging Tooltips solved!

It appeared to be that an active button remained in that state when
another region/editor became active. It then kept the button-activate
state, and therefore also the optional tooltip.

This only happened on fast moves, when a mousemove event was not passed
on anymore to the previously active subwindow.

It has been solved with a new notifier (SWINACTIVE), which gets sent on
new active regions. The screen listener then calls uiFreeActiveButtons()
to find out if buttons were still active somewhere else.

source/blender/editors/include/ED_screen.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_handlers.c
source/blender/editors/screen/screen_edit.c
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c

index f1665f2..71c732d 100644 (file)
@@ -95,14 +95,14 @@ void        ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
 void   ED_screens_initialize(struct wmWindowManager *wm);
 void   ED_screen_draw(struct wmWindow *win);
 void   ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
-void   ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
+void   ED_screen_do_listen(struct bContext *C, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc);
 bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, const char *name);
 void   ED_screen_set(struct bContext *C, struct bScreen *sc);
 void   ED_screen_delete(struct bContext *C, struct bScreen *sc);
 void   ED_screen_set_scene(struct bContext *C, struct Scene *scene);
 void   ED_screen_delete_scene(struct bContext *C, struct Scene *scene);
-void   ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event);
+void   ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event);
 void   ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
 void   ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
 void   ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh);
index db05b05..e938192 100644 (file)
@@ -322,6 +322,7 @@ void uiBlockSetEmboss(uiBlock *block, char dt);
 void uiFreeBlock(const struct bContext *C, uiBlock *block);
 void uiFreeBlocks(const struct bContext *C, struct ListBase *lb);
 void uiFreeInactiveBlocks(const struct bContext *C, struct ListBase *lb);
+void uiFreeActiveButtons(const struct bContext *C, struct bScreen *screen);
 
 void uiBlockSetRegion(uiBlock *block, struct ARegion *region);
 
index 67154a4..7c3cb00 100644 (file)
@@ -144,11 +144,11 @@ typedef struct uiHandleButtonData {
        float dragf, dragfstart;
        CBData *dragcbd;
 
-       /* menu open */
+       /* menu open (watch uiFreeActiveButtons) */
        uiPopupBlockHandle *menu;
        int menuretval;
        
-       /* search box */
+       /* search box (watch uiFreeActiveButtons) */
        ARegion *searchbox;
 
        /* post activate */
@@ -4595,6 +4595,27 @@ int ui_button_is_active(ARegion *ar)
        return (ui_but_find_activated(ar) != NULL);
 }
 
+/* is called by notifier */
+void uiFreeActiveButtons(const bContext *C, bScreen *screen)
+{
+       ScrArea *sa= screen->areabase.first;
+       
+       for(;sa; sa= sa->next) {
+               ARegion *ar= sa->regionbase.first;
+               for(;ar; ar= ar->next) {
+                       uiBut *but= ui_but_find_activated(ar);
+                       if(but) {
+                               uiHandleButtonData *data= but->active;
+                               
+                               if(data->menu==NULL && data->searchbox==NULL)
+                                       ui_button_active_free(C, but);
+                       }
+               }
+       }
+}
+
+
+
 /* returns TRUE if highlighted button allows drop of names */
 /* called in region context */
 int UI_but_active_drop_name(bContext *C)
index 44a7a7c..41354c8 100644 (file)
@@ -960,8 +960,9 @@ static void region_cursor_set(wmWindow *win, int swinid)
        }
 }
 
-void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
+void ED_screen_do_listen(bContext *C, wmNotifier *note)
 {
+       wmWindow *win= CTX_wm_window(C);
        
        /* generic notes */
        switch(note->category) {
@@ -973,8 +974,11 @@ void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
                        win->screen->do_draw= 1;
                        break;
                case NC_SCREEN:
+                       if(note->data==ND_SUBWINACTIVE)
+                               uiFreeActiveButtons(C, win->screen);
                        if(note->action==NA_EDITED)
                                win->screen->do_draw= win->screen->do_refresh= 1;
+                       break;
                case NC_SCENE:
                        if(note->data==ND_MODE)
                                region_cursor_set(win, note->swinid);                           
@@ -1217,8 +1221,10 @@ static void screen_cursor_set(wmWindow *win, wmEvent *event)
 
 /* called in wm_event_system.c. sets state vars in screen, cursors */
 /* event type is mouse move */
-void ED_screen_set_subwinactive(wmWindow *win, wmEvent *event)
+void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
 {
+       wmWindow *win= CTX_wm_window(C);
+       
        if(win->screen) {
                bScreen *scr= win->screen;
                ScrArea *sa;
@@ -1264,6 +1270,7 @@ void ED_screen_set_subwinactive(wmWindow *win, wmEvent *event)
                }
                else if(oldswin!=scr->subwinactive) {
                        region_cursor_set(win, scr->subwinactive);
+                       WM_event_add_notifier(C, NC_SCREEN|ND_SUBWINACTIVE, scr);
                }
        }
 }
index 82ef6a1..8748703 100644 (file)
@@ -179,6 +179,7 @@ typedef struct wmNotifier {
 #define ND_EDITOR_CHANGED      (6<<16) /*sent to new editors after switching to them*/
 #define ND_SCREENSET           (7<<16)
 #define ND_SKETCH                      (8<<16)
+#define ND_SUBWINACTIVE                (9<<16)
 
        /* NC_SCENE Scene */
 #define ND_SCENEBROWSE         (1<<16)
index e013bc8..ae61b3d 100644 (file)
@@ -270,7 +270,7 @@ void wm_event_do_notifiers(bContext *C)
                                CTX_wm_window_set(C, win);
 
                                /* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name+2, note->category); */
-                               ED_screen_do_listen(win, note);
+                               ED_screen_do_listen(C, note);
 
                                for(ar=win->screen->regionbase.first; ar; ar= ar->next) {
                                        ED_region_do_listen(ar, note);
@@ -1741,7 +1741,7 @@ void wm_event_do_handlers(bContext *C)
                        /* XXX to solve, here screen handlers? */
                        if(event->type==MOUSEMOVE) {
                                /* state variables in screen, cursors, also used in wm_draw.c */
-                               ED_screen_set_subwinactive(win, event); 
+                               ED_screen_set_subwinactive(C, event);   
                                /* for regions having custom cursors */
                                wm_paintcursor_test(C, event);
                        }