Changeset 8279 for trunk

Show
Ignore:
Timestamp:
07/12/11 14:33:25 (6 months ago)
Author:
westram
Message:
  • moved AW_window awar-create/read/write into member-functions
  • several fixes related to [8278]
    • if window-position is unknown in expose callback
      • set it again from awars and
      • delay WM_offset calculation using timed-callback
    • never save values into awars, if WM_offsets have not been calculated
    • make sure that window-position set and stored-in-awars is the same (in show_internal)
      • needed for correct WM_offset-calculation
      • popup-windows which are repositioned on show, no longer popup on (old) wrong position and then jump to wanted position (instead they instantly appear at wanted position).
    • only add expose-callback once
  • changed behavior of modal prompter windows
    • faster reaction (100ms instead of 500ms delay)
    • the window is not centered on mouse pos, instead its just moved that far that the mouse is inside the window.
    • considers WM_offsets
    • fallback to center-jump if window-position is unknown
Location:
trunk/WINDOW
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/WINDOW/AW_modal.cxx

    r7811 r8279  
    2626#define AWAR_QUESTION "tmp/question" 
    2727 
    28 #define AW_MESSAGE_LISTEN_DELAY 500 // look in ms whether a father died 
     28#define AW_MESSAGE_LISTEN_DELAY 100 // look in ms whether a father died 
    2929 
    3030int aw_message_cb_result; 
  • trunk/WINDOW/AW_window.cxx

    r8278 r8279  
    601601#define aw_awar_name_height(aww) aw_size_awar_name((aww), "height") 
    602602 
     603void AW_window::create_user_geometry_awars(int posx, int posy, int width, int height) { 
     604    get_root()->awar_int(aw_awar_name_posx(this), posx); 
     605    get_root()->awar_int(aw_awar_name_posy(this), posy); 
     606    get_root()->awar_int(aw_awar_name_width(this), width); 
     607    get_root()->awar_int(aw_awar_name_height(this), height); 
     608} 
     609 
     610 
     611void AW_window::store_size_in_awars(int width, int height) { 
     612    get_root()->awar(aw_awar_name_width(this))->write_int(width); 
     613    get_root()->awar(aw_awar_name_height(this))->write_int(height); 
     614} 
     615 
     616void AW_window::get_size_from_awars(int& width, int& height) { 
     617    width  = get_root()->awar(aw_awar_name_width(this))->read_int(); 
     618    height = get_root()->awar(aw_awar_name_height(this))->read_int(); 
     619} 
     620 
     621void AW_window::store_pos_in_awars(int posx, int posy) { 
     622    get_root()->awar(aw_awar_name_posx(this))->write_int(posx); 
     623    get_root()->awar(aw_awar_name_posy(this))->write_int(posy); 
     624} 
     625 
     626void AW_window::get_pos_from_awars(int& posx, int& posy) { 
     627    posx = get_root()->awar(aw_awar_name_posx(this))->read_int(); 
     628    posy = get_root()->awar(aw_awar_name_posy(this))->read_int(); 
     629} 
     630 
     631#undef aw_awar_name_posx 
     632#undef aw_awar_name_posy 
     633#undef aw_awar_name_width 
     634#undef aw_awar_name_height 
     635 
     636static void aw_onExpose_calc_WM_offsets(AW_window *aww); 
     637static void aw_calc_WM_offsets_delayed(AW_root *, AW_CL cl_aww, AW_CL) { aw_onExpose_calc_WM_offsets((AW_window*)cl_aww); } 
     638 
    603639static void aw_onExpose_calc_WM_offsets(AW_window *aww) { 
    604     if (p_aww(aww)->WM_top_offset != AW_CALC_OFFSET_ON_EXPOSE) return; // @@@ remove me when using called-once-expose-callbacks 
    605     aw_assert(p_aww(aww)->WM_top_offset == AW_CALC_OFFSET_ON_EXPOSE); 
    606  
    607     // get last position stored in properties 
    608     AW_root *root  = aww->get_root(); 
    609     int      oposx = root->awar(aw_awar_name_posx(aww))->read_int(); 
    610     int      oposy = root->awar(aw_awar_name_posy(aww))->read_int(); 
    611  
    612640    AW_window_Motif *motif = p_aww(aww); 
    613641 
    614     int posx, posy; 
    615     aww->get_window_pos(posx, posy); 
    616  
    617     if (posx == 0 && posy == 0) { // oops - motif has no idea where the window has been placed 
    618         // assume positions stored in awars are correct and use them.  
     642    int posx,  posy;  aww->get_window_content_pos(posx, posy); 
     643 
     644    bool knows_window_position = posx != 0 || posy != 0; 
     645 
     646    if (!knows_window_position) { // oops - motif has no idea where the window has been placed 
     647        // assume positions stored in awars are correct and use them. 
    619648        // This works around problems with unclickable GUI-elements when running on 'Unity' 
    620         aww->set_window_pos(oposx, oposy); 
    621         posx = oposx; 
    622         posy = oposy; 
    623     } 
    624  
    625     // calculate offset 
    626     motif->WM_top_offset  = posy-oposy; 
    627     motif->WM_left_offset = posx-oposx; 
    628 } 
    629  
    630 static void aw_onExpose_setPosFromAwars(AW_window *aww) { 
    631     AW_root *root  = aww->get_root(); 
    632     int oposx = root->awar(aw_awar_name_posx(aww))->read_int(); 
    633     int oposy = root->awar(aw_awar_name_posy(aww))->read_int(); 
    634          
    635     aww->set_window_pos(oposx, oposy); 
     649 
     650        int oposx, oposy; aww->get_pos_from_awars(oposx, oposy); 
     651        aww->set_window_frame_pos(oposx, oposy); 
     652 
     653        if (!motif->knows_WM_offset()) { 
     654            aww->get_root()->add_timed_callback(100, aw_calc_WM_offsets_delayed, (AW_CL)aww, 0); 
     655        } 
     656    } 
     657    else if (!motif->knows_WM_offset()) { 
     658        int oposx, oposy; aww->get_pos_from_awars(oposx, oposy); 
     659        // calculate offset 
     660        motif->WM_top_offset  = posy-oposy; 
     661        motif->WM_left_offset = posx-oposx; 
     662    } 
    636663} 
    637664 
     
    955982} 
    956983 
    957 void AW_window::set_window_pos(int x, int y) { 
     984void AW_window::set_window_frame_pos(int x, int y) { 
     985    // this will set the position of the frame around the client-area (see also WM_top_offset ..) 
    958986    XtVaSetValues(p_w->shell, XmNx, (int)x, XmNy, (int)y, NULL); 
    959987} 
    960 void AW_window::get_window_pos(int& xpos, int& ypos) { 
     988void AW_window::get_window_content_pos(int& xpos, int& ypos) { 
     989    // this will report the position of the client-area (see also WM_top_offset ..) 
    961990    unsigned short x, y; 
    962991    XtVaGetValues(p_w->shell, XmNx, &x, XmNy, &y, NULL); 
     
    16861715 
    16871716void aw_update_window_geometry_awars(AW_window *aww) { 
    1688     AW_root *root = aww->get_root(); 
     1717    AW_window_Motif *motif = p_aww(aww); 
    16891718 
    16901719    short          posx, posy; 
    16911720    unsigned short width, height, borderwidth; 
    1692     XtVaGetValues(p_aww(aww)->shell,                // bad hack 
     1721    XtVaGetValues(motif->shell, // bad hack 
    16931722                  XmNborderWidth, &borderwidth, 
    16941723                  XmNwidth, &width, 
     
    16981727                  NULL); 
    16991728 
    1700     if (p_aww(aww)->WM_top_offset != AW_CALC_OFFSET_ON_EXPOSE) { 
    1701         posy -= p_aww(aww)->WM_top_offset; 
    1702     } 
    1703     posx -= p_aww(aww)->WM_left_offset; // why is this not handled like posy? 
    1704  
    1705     if (posx<0) posx = 0; 
    1706     if (posy<0) posy = 0; 
    1707  
    1708     root->awar(aw_awar_name_width (aww))->write_int(width); 
    1709     root->awar(aw_awar_name_height(aww))->write_int(height); 
    1710     root->awar(aw_awar_name_posx (aww))->write_int(posx); 
    1711     root->awar(aw_awar_name_posy (aww))->write_int(posy); 
     1729    if (motif->knows_WM_offset()) { 
     1730        posy -= motif->WM_top_offset; 
     1731        posx -= motif->WM_left_offset; 
     1732 
     1733        if (posx<0) posx = 0; 
     1734        if (posy<0) posy = 0; 
     1735 
     1736        aww->store_pos_in_awars(posx, posy); 
     1737    } 
     1738#if defined(DEBUG) 
     1739    else { 
     1740        fprintf(stderr, " WM_offsets unknown. Did not update awars!\n"); 
     1741    } 
     1742#endif 
     1743    aww->store_size_in_awars(width, height); 
    17121744} 
    17131745 
     
    17911823        bool has_user_geometry = false; 
    17921824 
    1793         const char *temp = aw_awar_name_width(aww); 
    1794         root->awar_int(temp, width); 
     1825        aww->create_user_geometry_awars(posx, posy, width, height); 
     1826 
     1827        int user_width, user_height; aww->get_size_from_awars(user_width, user_height); 
     1828        int user_posx,  user_posy;   aww->get_pos_from_awars(user_posx,  user_posy); 
     1829 
    17951830        if (allow_resize) { 
    1796             int found_width = (int)root->awar(temp)->read_int(); 
    1797             if (width != found_width) { 
    1798                 has_user_geometry = true; 
    1799                 width = found_width; 
    1800             } 
    1801         } 
    1802  
    1803         temp = aw_awar_name_height(aww); 
    1804         root->awar_int(temp, height); 
    1805         if (allow_resize) { 
    1806             int found_height = (int)root->awar(temp)->read_int(); 
    1807             if (height != found_height) { 
    1808                 has_user_geometry = true; 
    1809                 height = found_height; 
    1810             } 
    1811         } 
    1812  
    1813         temp = aw_awar_name_posx(aww); 
    1814         root->awar_int(temp, posx)->set_minmax(0, 4000); 
     1831            if (width != user_width) { width = user_width; has_user_geometry = true; } 
     1832            if (height != user_height) { height = user_height; has_user_geometry = true; } 
     1833        } 
     1834 
    18151835        // @@@ FIXME:  maximum should be set to current screen size minus some offset 
    18161836        // to ensure that windows do not appear outside screen 
    1817         // same for posy below! 
    1818  
    1819         int found_posx = (int)root->awar(temp)->read_int(); 
    1820         if (posx != found_posx) { 
    1821             has_user_geometry = true; 
    1822             posx = found_posx; 
    1823         } 
    1824  
    1825         temp = aw_awar_name_posy(aww); 
    1826         root->awar_int(temp, posy)->set_minmax(0, 3000); 
    1827         int found_posy = (int)root->awar(temp)->read_int(); 
    1828         if (posy != found_posy) { 
    1829             has_user_geometry = true; 
    1830             posy = found_posy; 
    1831         } 
     1837        if (posx != user_posx) { posx = user_posx; has_user_geometry = true; } 
     1838        if (posy != user_posy) { posy = user_posy; has_user_geometry = true; } 
    18321839 
    18331840        if (has_user_geometry) { 
     
    18641871        GBK_terminatef("Failed to load icon pixmap for window '%s'\n", aww->window_defaults_name); 
    18651872    } 
    1866  
    1867 #if defined(DEBUG) && 0 
    1868     printf("aw_create_shell: pos=%i/%i size=%i%i\n", posx, posy, width, height); 
    1869 #endif // DEBUG 
    18701873 
    18711874    int focusPolicy = root->focus_follows_mouse ? XmPOINTER : XmEXPLICIT; 
     
    19601963} 
    19611964 
    1962 void AW_window_menu_modes::init(AW_root *root_in, const char *wid, const char *windowname, int  width, int height) { 
     1965void AW_window_menu_modes::init(AW_root *root_in, const char *wid, const char *windowname, int  width, int height) { // @@@ indentation 
    19631966    Widget      main_window; 
    19641967    Widget      help_popup; 
     
    21702173} 
    21712174 
    2172 void AW_window_menu::init(AW_root *root_in, const char *wid, const char *windowname, int width, int height) { 
     2175void AW_window_menu::init(AW_root *root_in, const char *wid, const char *windowname, int width, int height) { // @@@ indentation 
    21732176    Widget      main_window; 
    21742177    Widget      help_popup; 
     
    24032406} 
    24042407 
    2405 void AW_window_simple_menu::init(AW_root *root_in, const char *wid, const char *windowname) { 
     2408void AW_window_simple_menu::init(AW_root *root_in, const char *wid, const char *windowname) { // @@@ indentation 
    24062409    root = root_in; // for macro 
    24072410 
     
    31313134        else { 
    31323135            aw_assert(recalc_size_at_show == AW_RESIZE_USER); 
    3133             // check whether user size is too small and increase to minimum (aka default) 
    3134             int default_width, default_height; 
    3135             get_window_size(default_width, default_height); 
    3136             AW_root *tmp_root = get_root(); 
    3137             int user_width = tmp_root->awar(aw_awar_name_width(this))->read_int(); 
    3138             int user_height = tmp_root->awar(aw_awar_name_height(this))->read_int(); 
    3139  
    3140             if (user_width<default_width) user_width = default_width; 
    3141             if (user_height<default_height) user_height = default_height; 
     3136            // check whether user size is too small and increase to minimum window size 
     3137 
     3138            int min_width, min_height;   get_window_size(min_width, min_height); 
     3139            int user_width, user_height; get_size_from_awars(user_width, user_height); 
     3140 
     3141            if (user_width <min_width)  user_width  = min_width; 
     3142            if (user_height<min_height) user_height = min_height; 
    31423143 
    31433144            set_window_size(user_width, user_height); 
     
    31463147    } 
    31473148 
    3148     if (recalc_pos_at_show != AW_KEEP_POS) { 
     3149    { 
    31493150        int  posx, posy; 
    31503151        bool setPos = false; 
     
    31573158                int mx, my; if (!get_mouse_pos(mx, my)) goto FALLBACK_CENTER; 
    31583159                int width, height; get_window_size(width, height); 
    3159                 int wx, wy; get_window_pos(wx, wy); 
    3160  
    3161                 int wx2 = wx+width-1; 
    3162                 int wy2 = wy+height-1; 
    3163  
    3164                 if (mx<wx || mx>wx2 || my<wy || my>wy2) { // mouse is outside window 
     3160                int wx, wy; get_window_content_pos(wx, wy); 
     3161 
     3162                if (wx || wy) { 
     3163                    if (p_w->knows_WM_offset()) { 
     3164                        wx -= p_w->WM_left_offset; 
     3165                        wy -= p_w->WM_top_offset; 
     3166 
     3167                        width  += p_w->WM_left_offset; 
     3168                        height += p_w->WM_top_offset; 
     3169                    } 
     3170 
     3171                    int wx2 = wx+width-1; 
     3172                    int wy2 = wy+height-1; 
     3173 
     3174                    if (mx<wx) { setPos = true; wx = mx; } else if (mx>wx2) { setPos = true; wx = mx-width+1; } 
     3175                    if (my<wy) { setPos = true; wy = my; } else if (my>wy2) { setPos = true; wy = my-height+1; } 
     3176 
     3177                    posx = wx; 
     3178                    posy = wy; 
     3179                } 
     3180                else { 
    31653181                    setPos = true; 
    3166                     posx   = mx-width/2; // center window on mouse position 
     3182                    posx   = mx-width/2; 
    31673183                    posy   = my-height/2; 
    31683184                } 
     3185 
     3186                if (posx<0) posx = 0; 
     3187                if (posy<0) posy = 0; 
     3188 
    31693189                break; 
    31703190            } 
    31713191            case AW_REPOS_TO_CENTER: { 
    3172             FALLBACK_CENTER : 
     3192                  FALLBACK_CENTER : 
    31733193                int width, height; get_window_size(width, height); 
    31743194                int swidth, sheight; get_screen_size(swidth, sheight); 
     
    31813201 
    31823202            case AW_KEEP_POS: 
    3183                 aw_assert(0); 
    31843203                break; 
    31853204        } 
    31863205 
    3187         if (setPos) set_window_pos(posx, posy); // @@@ try if it's better to set this via aw_onExpose_setPosFromAwars 
     3206        if (setPos) store_pos_in_awars(posx, posy); 
     3207        else get_pos_from_awars(posx, posy); 
     3208 
     3209        set_window_frame_pos(posx, posy); // always set pos 
    31883210    } 
    31893211 
    31903212    XtPopup(p_w->shell, grab); 
    3191     if (p_w->WM_top_offset == AW_CALC_OFFSET_ON_EXPOSE) {              // very bad hack 
     3213    if (!expose_callback_added) { 
    31923214        set_expose_callback(AW_INFO_AREA, (AW_CB)aw_onExpose_calc_WM_offsets, 0, 0); // @@@ should be removed after it was called once 
    3193     } 
    3194     else if (recalc_pos_at_show == AW_KEEP_POS) { 
    3195         set_expose_callback(AW_INFO_AREA, (AW_CB)aw_onExpose_setPosFromAwars, 0, 0); // @@@ should be removed after it was called once 
     3215        expose_callback_added = true; 
    31963216    } 
    31973217} 
  • trunk/WINDOW/aw_window.hxx

    r7811 r8279  
    194194enum AW_PosRecalc { 
    195195    AW_KEEP_POS            = 0,                     // do not change position on show 
    196     AW_REPOS_TO_CENTER     = 1,                     // center the window on show 
     196    AW_REPOS_TO_CENTER     = 1,                     // center the window on show (unused atm) 
    197197    AW_REPOS_TO_MOUSE      = 2,                     // move the window under the current mouse position 
    198198    AW_REPOS_TO_MOUSE_ONCE = 3,                     // like AW_REPOS_TO_MOUSE, but only done once! 
     
    206206    aw_hide_cb         hide_cb; 
    207207 
     208    bool expose_callback_added; 
     209     
    208210    void all_menus_created() const; 
    209211    void create_toggle(const char *var_name, aw_toggle_data *tdata); 
     
    386388 
    387389 
     390    void create_user_geometry_awars(int posx, int posy, int width, int height); 
     391     
    388392    // ************** Control window size  ********* 
    389393    void set_window_size(int width, int height); 
     
    391395    void window_fit();                              // Recalculate the size of a window with buttons 
    392396 
     397    void store_size_in_awars(int width, int height); 
     398    void get_size_from_awars(int& width, int& height); 
     399 
    393400 
    394401    // ************** Control window position  ********* 
    395     void set_window_pos(int width, int height); 
    396     void get_window_pos(int& xpos, int& ypos); 
    397  
     402    void set_window_frame_pos(int xpos, int ypos); 
     403    void get_window_content_pos(int& xpos, int& ypos); 
     404 
     405    void store_pos_in_awars(int xpos, int ypos); 
     406    void get_pos_from_awars(int& xpos, int& ypos); 
     407     
     408     
    398409    // ***************** 
    399410 
  • trunk/WINDOW/aw_window_Xm.hxx

    r8278 r8279  
    301301 
    302302    AW_area_management *areas[AW_MAX_AREA]; 
    303     int                 WM_top_offset; // WM top area 
    304     int                 WM_left_offset; 
     303 
     304    int WM_top_offset;                 // correction between position set and position reported ( = size of window frame - in most cases!) 
     305    int WM_left_offset; 
     306 
     307    bool knows_WM_offset() const { return WM_top_offset != AW_CALC_OFFSET_ON_EXPOSE; } 
    305308 
    306309    AW_window_Motif();