changeset 356:81338758c3dd

- Added a workaround for segfaulting popup menus.
author jcid
date Sat, 27 Sep 2008 21:13:51 +0200
parents a51f2a345f4f
children 09a79e1ffea2
files src/html.cc src/menu.cc src/menu.hh src/plain.cc src/uicmd.cc src/uicmd.hh
diffstat 6 files changed, 61 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/src/html.cc	Sat Sep 27 15:36:16 2008 +0200
+++ b/src/html.cc	Sat Sep 27 21:13:51 2008 +0200
@@ -755,12 +755,14 @@
          // image menu
          if (link != -1)
             linkurl = html->links->get(link);
-         a_UIcmd_image_popup(bw, html->images->get(img)->url, linkurl);
+         const bool_t loaded_img = (html->images->get(img)->image == NULL);
+         a_UIcmd_image_popup(
+            bw, html->images->get(img)->url, loaded_img, linkurl);
          ret = true;
       } else {
          if (link == -1) {
             a_UIcmd_page_popup(bw, a_History_get_url(NAV_TOP_UIDX(bw)),
-                               bw->num_page_bugs ? bw->page_bugs->str:NULL,
+                               bw->num_page_bugs != 0,
                                html->unloadedImages());
             ret = true;
          } else {
--- a/src/menu.cc	Sat Sep 27 15:36:16 2008 +0200
+++ b/src/menu.cc	Sat Sep 27 21:13:51 2008 +0200
@@ -24,6 +24,7 @@
 #include "history.h"
 #include "html.hh"
 #include "ui.hh" // for (UI *)
+#include "timeout.hh"
 
 using namespace fltk;
 
@@ -33,12 +34,9 @@
 
 // (This data can be encapsulated inside a class for each popup, but
 //  as popups are modal, there's no need).
-// Weak reference to the popup's URL
-static const DilloUrl *popup_url = NULL;
+static DilloUrl *popup_url = NULL;
 // Weak reference to the popup's bw
 static BrowserWindow *popup_bw = NULL;
-// Weak reference to the page's HTML bugs
-static const char *popup_bugs = NULL;
 // History popup direction (-1 = back, 1 = forward).
 static int history_direction = -1; 
 // History popup, list of URL-indexes.
@@ -246,10 +244,22 @@
 }
 
 /*
+ * Manus are popped-up from this timeout callback so the events
+ * associated with the button are gone when it pops. This way we
+ * avoid a segfault when a new page replaces the page that issued
+ * the popup menu.
+ */
+static void Menu_popup_cb(void *data)
+{
+   ((PopupMenu *)data)->popup();
+   a_Timeout_remove();
+}
+
+/*
  * Page popup menu (construction & popup)
  */
 void a_Menu_page_popup(BrowserWindow *bw, const DilloUrl *url, 
-                       const char *bugs_txt, bool_t unloaded_imgs)
+                       bool_t has_bugs, bool_t unloaded_imgs)
 {
    // One menu for every browser window
    static PopupMenu *pm = 0;
@@ -258,8 +268,8 @@
    static Item *load_images_item = 0;
 
    popup_bw = bw;
-   popup_url = url;
-   popup_bugs = bugs_txt;
+   a_Url_free(popup_url);
+   popup_url = a_Url_dup(url);
 
    if (!pm) {
       Item *i;
@@ -287,20 +297,19 @@
       pm->end();
    }
 
-   if (bugs_txt == NULL)
-      view_page_bugs_item->deactivate();
+   if (has_bugs == TRUE)
+      view_page_bugs_item->activate();
    else
-      view_page_bugs_item->activate();
+      view_page_bugs_item->deactivate();
 
-   if (unloaded_imgs == TRUE)
+   if (unloaded_imgs == TRUE) {
       load_images_item->activate();
-   else
+      load_images_item->user_data(NULL); /* wildcard */
+   } else {
       load_images_item->deactivate();
+   }
 
-   // NULL is wildcard
-   load_images_item->user_data(NULL);
-
-   pm->popup();
+   a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
 }
 
 /*
@@ -312,7 +321,8 @@
    static PopupMenu *pm = 0;
 
    popup_bw = bw;
-   popup_url = url;
+   a_Url_free(popup_url);
+   popup_url = a_Url_dup(url);
    if (!pm) {
       Item *i;
       pm = new PopupMenu(0,0,0,0,"&LINK OPTIONS");
@@ -335,25 +345,27 @@
       pm->end();
    }
 
-   pm->popup();
+   a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
 }
 
 /*
  * Image popup menu (construction & popup)
  */
 void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url,
-                        DilloUrl *link_url)
+                        bool_t loaded_img, DilloUrl *link_url)
 {
    // One menu for every browser window
    static PopupMenu *pm = 0;
    // Active/inactive control.
    static Item *link_menuitem = 0;
-   static Item *load_menuitem = 0;
-
-   DilloUrl *userdata_url = a_Url_dup(url);
+   static Item *load_img_menuitem = 0;
+   static DilloUrl *popup_link_url = NULL;
 
    popup_bw = bw;
-   popup_url = url;
+   a_Url_free(popup_url);
+   popup_url = a_Url_dup(url);
+   a_Url_free(popup_link_url);
+   popup_link_url = a_Url_dup(link_url);
    
    if (!pm) {
       Item *i;
@@ -366,7 +378,7 @@
        i = new Item("Open Image in New Tab");
        i->callback(Menu_open_url_nt_cb);
        new Divider();
-       i = load_menuitem = new Item("Load image");
+       i = load_img_menuitem = new Item("Load image");
        i->callback(Menu_load_images_cb);
        i = new Item("Bookmark this Image");
        i->callback(Menu_add_bookmark_cb);
@@ -383,21 +395,21 @@
       pm->end();
    }
 
-   // point to this item initially
-   pm->item(load_menuitem);
+   if (loaded_img) {
+      load_img_menuitem->deactivate();
+   } else {
+      load_img_menuitem->activate();
+      load_img_menuitem->user_data(popup_url);
+   }
 
    if (link_url) {
-      link_menuitem->user_data(link_url);
+      link_menuitem->user_data(popup_link_url);
       link_menuitem->activate();
    } else {
       link_menuitem->deactivate();
    }
 
-   load_menuitem->user_data(userdata_url);
- 
-   pm->popup();
-
-   a_Url_free(userdata_url);
+   a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
 }
 
 /*
@@ -409,7 +421,8 @@
    static PopupMenu *pm = 0;
 
    popup_bw = bw;
-   popup_url = url;
+   a_Url_free(popup_url);
+   popup_url = a_Url_dup(url);
    if (!pm) {
       Item *i;
       pm = new PopupMenu(0,0,0,0,"&BUG METER OPTIONS");
--- a/src/menu.hh	Sat Sep 27 15:36:16 2008 +0200
+++ b/src/menu.hh	Sat Sep 27 21:13:51 2008 +0200
@@ -8,10 +8,10 @@
 #endif /* __cplusplus */
 
 void a_Menu_page_popup(BrowserWindow *bw, const DilloUrl *url,
-                       const char *bugs_txt, bool_t unloaded_imgs);
+                       bool_t has_bugs, bool_t unloaded_imgs);
 void a_Menu_link_popup(BrowserWindow *bw, const DilloUrl *url);
 void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url,
-                        DilloUrl *link_url);
+                        bool_t loaded_img, DilloUrl *link_url);
 void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url);
 void a_Menu_history_popup(BrowserWindow *bw, int direction);
 
--- a/src/plain.cc	Sat Sep 27 15:36:16 2008 +0200
+++ b/src/plain.cc	Sat Sep 27 21:13:51 2008 +0200
@@ -139,7 +139,7 @@
    _MSG("DilloPlain::PlainEventReceiver::buttonPress\n");
 
    if (event->button == 3) {
-      a_UIcmd_page_popup(plain->bw, plain->url, NULL, 1);
+      a_UIcmd_page_popup(plain->bw, plain->url, FALSE, FALSE);
       return true;
    }
    return false;
--- a/src/uicmd.cc	Sat Sep 27 15:36:16 2008 +0200
+++ b/src/uicmd.cc	Sat Sep 27 21:13:51 2008 +0200
@@ -588,9 +588,9 @@
  * Popup the page menu
  */
 void a_UIcmd_page_popup(void *vbw, const DilloUrl *url,
-                        const char *bugs_txt, bool_t unloaded_imgs)
+                        bool_t has_bugs, bool_t unloaded_imgs)
 {
-   a_Menu_page_popup((BrowserWindow*)vbw, url, bugs_txt, unloaded_imgs);
+   a_Menu_page_popup((BrowserWindow*)vbw, url, has_bugs, unloaded_imgs);
 }
 
 /*
@@ -604,9 +604,10 @@
 /*
  * Pop up the image menu
  */
-void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, DilloUrl *link_url)
+void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img,
+                         DilloUrl *link_url)
 {
-   a_Menu_image_popup((BrowserWindow*)vbw, url, link_url);
+   a_Menu_image_popup((BrowserWindow*)vbw, url, loaded_img, link_url);
 }
 
 /*
--- a/src/uicmd.hh	Sat Sep 27 15:36:16 2008 +0200
+++ b/src/uicmd.hh	Sat Sep 27 21:13:51 2008 +0200
@@ -35,9 +35,10 @@
 void a_UIcmd_focus_main_area(BrowserWindow *bw);
 void a_UIcmd_focus_location(void *vbw);
 void a_UIcmd_page_popup(void *vbw, const DilloUrl *url,
-                        const char *bugs_txt, bool_t unloaded_imgs);
+                        bool_t has_bugs, bool_t unloaded_imgs);
 void a_UIcmd_link_popup(void *vbw, const DilloUrl *url);
-void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, DilloUrl *link_url);
+void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img,
+                         DilloUrl *link_url);
 void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr);
 void a_UIcmd_view_page_source(const DilloUrl *url);
 void a_UIcmd_view_page_bugs(void *vbw);