aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ephy-automation.c2
-rw-r--r--src/ephy-notebook.c100
-rw-r--r--src/ephy-notebook.h3
-rw-r--r--src/ephy-session.c14
-rw-r--r--src/ephy-shell.c9
-rw-r--r--src/ephy-shell.h1
-rw-r--r--src/ephy-tab.c153
-rw-r--r--src/ephy-tab.h4
-rw-r--r--src/ephy-window.c294
-rw-r--r--src/ephy-window.h5
10 files changed, 434 insertions, 151 deletions
diff --git a/src/ephy-automation.c b/src/ephy-automation.c
index 99fb8071a..84b155a8a 100644
--- a/src/ephy-automation.c
+++ b/src/ephy-automation.c
@@ -106,7 +106,7 @@ impl_ephy_automation_loadUrlWithStartupId (PortableServer_Servant _servant,
}
ephy_shell_new_tab_full (ephy_shell, window, NULL, url, flags,
- EPHY_EMBED_CHROME_ALL, user_time);
+ EPHY_EMBED_CHROME_ALL, FALSE, user_time);
}
static void
diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c
index 02bf907f6..8ba8c29ba 100644
--- a/src/ephy-notebook.c
+++ b/src/ephy-notebook.c
@@ -67,9 +67,12 @@ struct _EphyNotebookPrivate
GtkTooltips *title_tips;
guint tabs_vis_notifier_id;
gulong motion_notify_handler_id;
- gint x_start, y_start;
- gboolean drag_in_progress;
- gboolean show_tabs;
+ int x_start;
+ int y_start;
+
+ guint drag_in_progress : 1;
+ guint show_tabs : 1;
+ guint dnd_enabled : 1;
};
static void ephy_notebook_init (EphyNotebook *notebook);
@@ -92,6 +95,13 @@ static guint n_url_drag_types = G_N_ELEMENTS (url_drag_types);
enum
{
+ PROP_0,
+ PROP_DND_ENABLED,
+ PROP_SHOW_TABS
+};
+
+enum
+{
TAB_ADDED,
TAB_REMOVED,
TABS_REORDERED,
@@ -142,6 +152,57 @@ ephy_notebook_get_type (void)
return type;
}
+void
+ephy_notebook_set_dnd_enabled (EphyNotebook *notebook,
+ gboolean enabled)
+{
+ EphyNotebookPrivate *priv = notebook->priv;
+
+ priv->dnd_enabled = enabled;
+ /* FIXME abort any DNDs in progress */
+
+ g_object_notify (G_OBJECT (notebook), "dnd-enabled");
+}
+
+static void
+ephy_notebook_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EphyNotebook *notebook = EPHY_NOTEBOOK (object);
+ EphyNotebookPrivate *priv = notebook->priv;
+
+ switch (prop_id)
+ {
+ case PROP_DND_ENABLED:
+ g_value_set_boolean (value, priv->dnd_enabled);
+ break;
+ case PROP_SHOW_TABS:
+ g_value_set_boolean (value, priv->show_tabs);
+ break;
+ }
+}
+
+static void
+ephy_notebook_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EphyNotebook *notebook = EPHY_NOTEBOOK (object);
+
+ switch (prop_id)
+ {
+ case PROP_DND_ENABLED:
+ ephy_notebook_set_dnd_enabled (notebook, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_TABS:
+ ephy_notebook_set_show_tabs (notebook, g_value_get_boolean (value));
+ break;
+ }
+}
+
static void
ephy_notebook_class_init (EphyNotebookClass *klass)
{
@@ -150,6 +211,8 @@ ephy_notebook_class_init (EphyNotebookClass *klass)
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = ephy_notebook_finalize;
+ object_class->get_property = ephy_notebook_get_property;
+ object_class->set_property = ephy_notebook_set_property;
signals[TAB_ADDED] =
g_signal_new ("tab_added",
@@ -201,7 +264,23 @@ ephy_notebook_class_init (EphyNotebookClass *klass)
1,
EPHY_TYPE_TAB);
- g_type_class_add_private (object_class, sizeof(EphyNotebookPrivate));
+ g_object_class_install_property (object_class,
+ PROP_DND_ENABLED,
+ g_param_spec_boolean ("dnd-enabled",
+ "DND enabled",
+ "Whether the notebook allows tab reordering by DND",
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SHOW_TABS,
+ g_param_spec_boolean ("show-tabs",
+ "Show tabs",
+ "Whether the notebook shows the tabs bar",
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (EphyNotebookPrivate));
}
static EphyNotebook *
@@ -476,6 +555,9 @@ move_tab_to_another_notebook (EphyNotebook *src,
g_assert (EPHY_IS_NOTEBOOK (dest));
g_assert (dest != src);
+ /* Check if the dest notebook can accept the drag */
+ if (!dest->priv->dnd_enabled) return;
+
cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (src));
tab = EPHY_TAB (gtk_notebook_get_nth_page (GTK_NOTEBOOK (src), cur_page));
@@ -543,10 +625,13 @@ button_press_cb (EphyNotebook *notebook,
GdkEventButton *event,
gpointer data)
{
- gint tab_clicked = find_tab_num_at_pos (notebook,
- event->x_root,
- event->y_root);
+ int tab_clicked;
+
+ if (!notebook->priv->dnd_enabled) return FALSE;
+
+ tab_clicked = find_tab_num_at_pos (notebook, event->x_root, event->y_root);
+ /* FIXME: how could there be a drag in progress!? */
if (notebook->priv->drag_in_progress)
{
return TRUE;
@@ -705,6 +790,7 @@ ephy_notebook_init (EphyNotebook *notebook)
gtk_object_sink (GTK_OBJECT (notebook->priv->title_tips));
notebook->priv->show_tabs = TRUE;
+ notebook->priv->dnd_enabled = TRUE;
g_signal_connect (notebook, "button-press-event",
(GCallback)button_press_cb, NULL);
diff --git a/src/ephy-notebook.h b/src/ephy-notebook.h
index 19cdc2f3a..04ae54fcd 100644
--- a/src/ephy-notebook.h
+++ b/src/ephy-notebook.h
@@ -85,6 +85,9 @@ void ephy_notebook_move_tab (EphyNotebook *src,
void ephy_notebook_set_show_tabs (EphyNotebook *nb,
gboolean show_tabs);
+void ephy_notebook_set_dnd_enabled (EphyNotebook *nb,
+ gboolean enabled);
+
G_END_DECLS
#endif /* EPHY_NOTEBOOK_H */
diff --git a/src/ephy-session.c b/src/ephy-session.c
index 68e448504..a54e81401 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -926,20 +926,22 @@ ephy_session_remove_window (EphySession *session,
* need to take an action (like opening an url) on
* a window but you dont have a target window.
*
- * Return value: the current active browser window, or NULL of there is none.
+ * Return value: the current active non-popup browser window, or NULL of there is none.
**/
EphyWindow *
ephy_session_get_active_window (EphySession *session)
{
- GList *first;
+ EphyWindow *window = NULL;
+ GList *l;
g_return_val_if_fail (EPHY_IS_SESSION (session), NULL);
- first = session->priv->windows;
- if (first != NULL)
+ for (l = session->priv->windows; l != NULL; l = l->next)
{
- return EPHY_WINDOW (first->data);
+ window = EPHY_WINDOW (l->data);
+
+ if (ephy_window_get_is_popup (window) == FALSE) break;
}
- return NULL;
+ return window;
}
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 9babb803b..807faff3b 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -182,7 +182,7 @@ ephy_shell_new_window_cb (EphyEmbedSingle *single,
new_tab = ephy_shell_new_tab_full
(shell,
EPHY_IS_WINDOW (parent) ? EPHY_WINDOW (parent) : NULL,
- NULL, NULL, flags, chromemask, 0);
+ NULL, NULL, flags, chromemask, TRUE, 0);
return ephy_tab_get_embed (new_tab);
}
@@ -650,6 +650,7 @@ load_homepage (EphyEmbed *embed)
* @previous_tab: the referrer tab or %NULL
* @url: an url to load or %NULL
* @chrome: a #EphyEmbedChrome mask to use if creating a new window
+ * @is_popup: whether the new window is a popup
* @user_time: a timestamp, or 0
*
* Create a new tab and the parent window when necessary.
@@ -664,6 +665,7 @@ ephy_shell_new_tab_full (EphyShell *shell,
const char *url,
EphyNewTabFlags flags,
EphyEmbedChrome chrome,
+ gboolean is_popup,
guint32 user_time)
{
EphyWindow *window;
@@ -680,6 +682,7 @@ ephy_shell_new_tab_full (EphyShell *shell,
if (flags & EPHY_NEW_TAB_IN_EXISTING_WINDOW) in_new_window = FALSE;
in_new_window = in_new_window && !eel_gconf_get_boolean (CONF_LOCKDOWN_FULLSCREEN);
+ g_return_val_if_fail (in_new_window || !is_popup, NULL);
jump_to = (flags & EPHY_NEW_TAB_JUMP) != 0;
@@ -692,7 +695,7 @@ ephy_shell_new_tab_full (EphyShell *shell,
}
else
{
- window = ephy_window_new_with_chrome (chrome);
+ window = ephy_window_new_with_chrome (chrome, is_popup);
}
toolbar = EPHY_TOOLBAR (ephy_window_get_toolbar (window));
@@ -764,7 +767,7 @@ ephy_shell_new_tab (EphyShell *shell,
{
return ephy_shell_new_tab_full (shell, parent_window,
previous_tab, url, flags,
- EPHY_EMBED_CHROME_ALL, 0);
+ EPHY_EMBED_CHROME_ALL, FALSE, 0);
}
/**
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index 32e5f9383..17319d79f 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -130,6 +130,7 @@ EphyTab *ephy_shell_new_tab_full (EphyShell *shell,
const char *url,
EphyNewTabFlags flags,
EphyEmbedChrome chrome,
+ gboolean is_popup,
guint32 user_time);
GObject *ephy_shell_get_session (EphyShell *shell);
diff --git a/src/ephy-tab.c b/src/ephy-tab.c
index 09debb6f1..db7a005c2 100644
--- a/src/ephy-tab.c
+++ b/src/ephy-tab.c
@@ -87,10 +87,12 @@ struct _EphyTabPrivate
GSList *shown_popups;
EphyTabNavigationFlags nav_flags;
EphyEmbedDocumentType document_type;
+ guint idle_resize_handler;
};
static void ephy_tab_class_init (EphyTabClass *klass);
static void ephy_tab_init (EphyTab *tab);
+static void ephy_tab_dispose (GObject *object);
static void ephy_tab_finalize (GObject *object);
enum
@@ -343,7 +345,8 @@ ephy_tab_class_init (EphyTabClass *class)
parent_class = g_type_class_peek_parent (class);
- object_class->finalize = ephy_tab_finalize;
+ object_class->dispose = ephy_tab_dispose;
+ object_class->finalize = ephy_tab_finalize;
object_class->get_property = ephy_tab_get_property;
object_class->set_property = ephy_tab_set_property;
@@ -632,16 +635,20 @@ popups_manager_show_all (EphyTab *tab)
static char *
popups_manager_new_window_info (EphyWindow *window)
{
+ EphyTab *tab;
EphyEmbedChrome chrome;
+ gboolean is_popup;
char *features;
- int w, h;
- g_object_get (window, "chrome", &chrome, NULL);
- gtk_window_get_size (GTK_WINDOW (window), &w, &h);
+ g_object_get (window, "chrome", &chrome, "is-popup", &is_popup, NULL);
+ g_return_val_if_fail (is_popup, g_strdup (""));
+
+ tab = ephy_window_get_active_tab (window);
+ g_return_val_if_fail (tab != NULL, g_strdup (""));
features = g_strdup_printf
("width=%d,height=%d,menubar=%d,status=%d,toolbar=%d",
- w, h,
+ tab->priv->width, tab->priv->height,
(chrome & EPHY_EMBED_CHROME_MENUBAR) > 0,
(chrome & EPHY_EMBED_CHROME_STATUSBAR) > 0,
(chrome & EPHY_EMBED_CHROME_TOOLBAR) > 0);
@@ -746,17 +753,31 @@ popups_manager_reset (EphyTab *tab)
}
static void
-ephy_tab_finalize (GObject *object)
+ephy_tab_dispose (GObject *object)
{
- EphyTab *tab = EPHY_TAB (object);
+ EphyTab *tab = EPHY_TAB (object);
+ EphyTabPrivate *priv = tab->priv;
- g_idle_remove_by_data (tab);
+ if (priv->idle_resize_handler != 0)
+ {
+ g_source_remove (priv->idle_resize_handler);
+ priv->idle_resize_handler = 0;
+ }
- g_free (tab->priv->title);
- g_free (tab->priv->address);
- g_free (tab->priv->icon_address);
- g_free (tab->priv->link_message);
- g_free (tab->priv->status_message);
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+ephy_tab_finalize (GObject *object)
+{
+ EphyTab *tab = EPHY_TAB (object);
+ EphyTabPrivate *priv = tab->priv;
+
+ g_free (priv->title);
+ g_free (priv->address);
+ g_free (priv->icon_address);
+ g_free (priv->link_message);
+ g_free (priv->status_message);
popups_manager_reset (tab);
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -782,6 +803,17 @@ address_has_web_scheme (const char *address)
return has_web_scheme;
}
+static gboolean
+let_me_resize_hack (EphyTab *tab)
+{
+ EphyTabPrivate *priv = tab->priv;
+
+ gtk_widget_set_size_request (GTK_WIDGET (tab), -1, -1);
+
+ priv->idle_resize_handler = 0;
+ return FALSE;
+}
+
/* Public functions */
/**
@@ -938,6 +970,54 @@ ephy_tab_get_size (EphyTab *tab, int *width, int *height)
}
/**
+ * ephy_tab_set_size:
+ * @tab: an #EphyTab
+ * @width:
+ * @height:
+ *
+ * Sets the size of @tab. This is not guaranteed to actually resize the tab.
+ **/
+void
+ephy_tab_set_size (EphyTab *tab,
+ int width,
+ int height)
+{
+ EphyTabPrivate *priv = tab->priv;
+ GtkWidget *widget = GTK_WIDGET (tab);
+ GtkAllocation allocation;
+
+ priv->width = width;
+ priv->height = height;
+
+ gtk_widget_set_size_request (widget, width, height);
+
+ /* HACK: When the web site changes both width and height,
+ * we will first get a width change, then a height change,
+ * without actually resizing the window in between (since
+ * that happens only on idle).
+ * If we don't set the allocation, GtkMozEmbed doesn't tell
+ * mozilla the new width, so the height change sets the width
+ * back to the old value!
+ */
+ allocation.x = widget->allocation.x;
+ allocation.y = widget->allocation.y;
+ allocation.width = width;
+ allocation.height = height;
+ gtk_widget_size_allocate (widget, &allocation);
+
+ /* HACK: reset widget requisition after the container
+ * has been resized. It appears to be the only way
+ * to have the window sized according to embed
+ * size correctly.
+ */
+ if (priv->idle_resize_handler == 0)
+ {
+ priv->idle_resize_handler =
+ g_idle_add ((GSourceFunc) let_me_resize_hack, tab);
+ }
+}
+
+/**
* ephy_tab_get_visibility:
* @tab: an #EphyTab
*
@@ -1330,14 +1410,6 @@ ephy_tab_popup_blocked_cb (EphyEmbed *embed, const char *url,
popups_manager_add (tab, url, features);
}
-static gboolean
-let_me_resize_hack (GtkWidget *tab)
-{
- gtk_widget_set_size_request (tab, -1, -1);
-
- return FALSE;
-}
-
static void
ephy_tab_visibility_cb (EphyEmbed *embed, gboolean visibility,
EphyTab *tab)
@@ -1379,42 +1451,6 @@ ephy_tab_destroy_brsr_cb (EphyEmbed *embed, EphyTab *tab)
ephy_notebook_remove_tab (EPHY_NOTEBOOK (notebook), tab);
}
-static void
-ephy_tab_size_to_cb (EphyEmbed *embed, gint width, gint height,
- EphyTab *tab)
-{
- GtkWidget *notebook;
- EphyWindow *window;
-
- LOG ("ephy_tab_size_to_cb tab %p width %d height %d", tab, width, height);
-
- tab->priv->width = width;
- tab->priv->height = height;
-
- window = ephy_tab_get_window (tab);
- notebook = ephy_window_get_notebook (window);
-
- /* Do not resize window with multiple tabs.
- * Do not resize window already showed because
- * it's not possible to calculate a sensible window
- * size based on the embed size */
- if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) == 1 &&
- !tab->priv->visibility)
- {
- gtk_widget_set_size_request
- (GTK_WIDGET (tab), width, height);
-
- /* HACK reset widget requisition after the container
- * has been resized. It appears to be the only way
- * to have the window sized according to embed
- * size correctly.
- */
-
- g_idle_add ((GSourceFunc) let_me_resize_hack, tab);
- }
-}
-
-
static gboolean
open_link_in_new_tab (EphyTab *tab,
const char *link_address)
@@ -1637,9 +1673,6 @@ ephy_tab_init (EphyTab *tab)
g_signal_connect_object (embed, "destroy_browser",
G_CALLBACK (ephy_tab_destroy_brsr_cb),
tab, 0);
- g_signal_connect_object (embed, "size_to",
- G_CALLBACK (ephy_tab_size_to_cb),
- tab, 0);
g_signal_connect_object (embed, "ge_dom_mouse_click",
G_CALLBACK (ephy_tab_dom_mouse_click_cb),
tab, 0);
diff --git a/src/ephy-tab.h b/src/ephy-tab.h
index f341f6887..a21f0dfa5 100644
--- a/src/ephy-tab.h
+++ b/src/ephy-tab.h
@@ -99,6 +99,10 @@ void ephy_tab_get_size (EphyTab *tab,
int *width,
int *height);
+void ephy_tab_set_size (EphyTab *tab,
+ int width,
+ int height);
+
const char *ephy_tab_get_status_message (EphyTab *tab);
const char *ephy_tab_get_title (EphyTab *tab);
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 859801e72..b24ebfa6e 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -77,6 +77,9 @@
static void ephy_window_class_init (EphyWindowClass *klass);
static void ephy_window_link_iface_init (EphyLinkIface *iface);
static void ephy_window_init (EphyWindow *gs);
+static GObject *ephy_window_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params);
static void ephy_window_finalize (GObject *object);
static void ephy_window_show (GtkWidget *widget);
static EphyTab *ephy_window_open_link (EphyLink *link,
@@ -415,6 +418,7 @@ struct _EphyWindowPrivate
guint tab_message_cid;
guint help_message_cid;
EphyEmbedChrome chrome;
+ guint idle_resize_handler;
guint disable_arbitrary_url_notifier_id;
guint disable_bookmark_editing_notifier_id;
@@ -432,6 +436,7 @@ struct _EphyWindowPrivate
guint fullscreen_mode : 1;
guint ppv_mode : 1;
guint should_save_chrome : 1;
+ guint is_popup : 1;
};
enum
@@ -439,7 +444,8 @@ enum
PROP_0,
PROP_ACTIVE_TAB,
PROP_CHROME,
- PROP_PPV_MODE
+ PROP_PPV_MODE,
+ PROP_SINGLE_TAB_MODE
};
static GObjectClass *parent_class = NULL;
@@ -520,20 +526,29 @@ get_toolbar_visibility (EphyWindow *window)
}
static void
-get_chromes_visibility (EphyWindow *window, gboolean *show_menubar,
- gboolean *show_statusbar, gboolean *show_toolbar,
- gboolean *show_bookmarksbar)
+get_chromes_visibility (EphyWindow *window,
+ gboolean *show_menubar,
+ gboolean *show_statusbar,
+ gboolean *show_toolbar,
+ gboolean *show_bookmarksbar,
+ gboolean *show_tabsbar)
{
- EphyEmbedChrome flags = window->priv->chrome;
+ EphyWindowPrivate *priv = window->priv;
+ EphyEmbedChrome flags = priv->chrome;
if (window->priv->ppv_mode)
{
- *show_menubar = *show_statusbar = *show_toolbar = *show_bookmarksbar = FALSE;
+ *show_menubar = *show_statusbar
+ = *show_toolbar
+ = *show_bookmarksbar
+ = *show_tabsbar
+ = FALSE;
}
else if (window->priv->fullscreen_mode)
{
*show_toolbar = (flags & EPHY_EMBED_CHROME_TOOLBAR) != 0;
*show_menubar = *show_statusbar = *show_bookmarksbar = FALSE;
+ *show_tabsbar = !priv->is_popup;
}
else
{
@@ -541,6 +556,7 @@ get_chromes_visibility (EphyWindow *window, gboolean *show_menubar,
*show_statusbar = (flags & EPHY_EMBED_CHROME_STATUSBAR) != 0;
*show_toolbar = (flags & EPHY_EMBED_CHROME_TOOLBAR) != 0;
*show_bookmarksbar = (flags & EPHY_EMBED_CHROME_BOOKMARKSBAR) != 0;
+ *show_tabsbar = !priv->is_popup;
}
}
@@ -549,13 +565,13 @@ sync_chromes_visibility (EphyWindow *window)
{
EphyWindowPrivate *priv = window->priv;
GtkWidget *menubar;
- gboolean show_statusbar, show_menubar, show_toolbar, show_bookmarksbar;
+ gboolean show_statusbar, show_menubar, show_toolbar, show_bookmarksbar, show_tabsbar;
if (priv->closing) return;
get_chromes_visibility (window, &show_menubar,
&show_statusbar, &show_toolbar,
- &show_bookmarksbar);
+ &show_bookmarksbar, &show_tabsbar);
menubar = gtk_ui_manager_get_widget (window->priv->manager, "/menubar");
g_assert (menubar != NULL);
@@ -567,6 +583,8 @@ sync_chromes_visibility (EphyWindow *window)
ephy_toolbar_set_lock_visibility (priv->toolbar, !show_statusbar);
+ ephy_notebook_set_show_tabs (EPHY_NOTEBOOK (priv->notebook), show_tabsbar);
+
if (priv->fullscreen_popup != NULL)
{
g_object_set (priv->fullscreen_popup, "visible", !show_toolbar, NULL);
@@ -980,11 +998,11 @@ update_chromes_actions (EphyWindow *window)
{
GtkActionGroup *action_group = window->priv->action_group;
GtkAction *action;
- gboolean show_statusbar, show_menubar, show_toolbar, show_bookmarksbar;
+ gboolean show_statusbar, show_menubar, show_toolbar, show_bookmarksbar, show_tabsbar;
get_chromes_visibility (window, &show_menubar,
&show_statusbar, &show_toolbar,
- &show_bookmarksbar);
+ &show_bookmarksbar, &show_tabsbar);
action = gtk_action_group_get_action (action_group, "ViewToolbar");
g_signal_handlers_block_by_func (G_OBJECT (action),
@@ -1038,11 +1056,15 @@ update_print_actions (EphyWindow *window,
static void
update_actions_sensitivity (EphyWindow *window)
{
- GtkActionGroup *action_group = window->priv->action_group;
- GtkActionGroup *popups_action_group = window->priv->popups_action_group;
+ EphyWindowPrivate *priv = window->priv;
+ GtkActionGroup *action_group = priv->action_group;
+ GtkActionGroup *popups_action_group = priv->popups_action_group;
GtkAction *action;
gboolean bookmarks_editable, save_to_disk, fullscreen;
+ action = gtk_action_group_get_action (action_group, "FileNewTab");
+ g_object_set (action, "sensitive", !priv->is_popup, NULL);
+
action = gtk_action_group_get_action (action_group, "ViewToolbar");
g_object_set (action, "sensitive", eel_gconf_key_is_writable (CONF_WINDOWS_SHOW_TOOLBARS), NULL);
@@ -1528,12 +1550,15 @@ sync_tab_title (EphyTab *tab, GParamSpec *pspec, EphyWindow *window)
}
static void
-sync_tab_visibility (EphyTab *tab, GParamSpec *pspec, EphyWindow *window)
+sync_tab_visibility (EphyTab *tab,
+ GParamSpec *pspec,
+ EphyWindow *window)
{
+ EphyWindowPrivate *priv = window->priv;
GList *l, *tabs;
gboolean visible = FALSE;
- if (window->priv->closing) return;
+ if (priv->closing) return;
tabs = ephy_window_get_tabs (window);
for (l = tabs; l != NULL; l = l->next)
@@ -1549,14 +1574,7 @@ sync_tab_visibility (EphyTab *tab, GParamSpec *pspec, EphyWindow *window)
}
g_list_free (tabs);
- if (visible)
- {
- gtk_widget_show (GTK_WIDGET(window));
- }
- else
- {
- gtk_widget_hide (GTK_WIDGET (window));
- }
+ g_object_set (window, "visible", visible, NULL);
}
static void
@@ -1753,8 +1771,11 @@ update_popups_tooltips (EphyWindow *window, EphyEmbedEvent *event)
}
static void
-show_embed_popup (EphyWindow *window, EphyTab *tab, EphyEmbedEvent *event)
+show_embed_popup (EphyWindow *window,
+ EphyTab *tab,
+ EphyEmbedEvent *event)
{
+ EphyWindowPrivate *priv = window->priv;
GtkActionGroup *action_group;
GtkAction *action;
EphyEmbedEventContext context;
@@ -1765,7 +1786,7 @@ show_embed_popup (EphyWindow *window, EphyTab *tab, EphyEmbedEvent *event)
guint button;
/* Do not show the menu in print preview mode */
- if (window->priv->ppv_mode)
+ if (priv->ppv_mode)
{
return;
}
@@ -1824,7 +1845,7 @@ show_embed_popup (EphyWindow *window, EphyTab *tab, EphyEmbedEvent *event)
update_popups_tooltips (window, event);
- widget = gtk_ui_manager_get_widget (window->priv->manager, popup);
+ widget = gtk_ui_manager_get_widget (priv->manager, popup);
g_return_if_fail (widget != NULL);
action_group = window->priv->popups_action_group;
@@ -1834,7 +1855,7 @@ show_embed_popup (EphyWindow *window, EphyTab *tab, EphyEmbedEvent *event)
action = gtk_action_group_get_action (action_group, "OpenLinkInNewWindow");
g_object_set (action, "sensitive", can_open_in_new, FALSE);
action = gtk_action_group_get_action (action_group, "OpenLinkInNewTab");
- g_object_set (action, "sensitive", can_open_in_new, FALSE);
+ g_object_set (action, "sensitive", can_open_in_new && !priv->is_popup, FALSE);
g_object_set_data_full (G_OBJECT (window), "context_event",
g_object_ref (event),
@@ -1875,6 +1896,70 @@ tab_context_menu_cb (EphyEmbed *embed,
return TRUE;
}
+static gboolean
+let_me_resize_hack (EphyWindow *window)
+{
+ EphyWindowPrivate *priv = window->priv;
+
+ gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
+
+ priv->idle_resize_handler = 0;
+ return FALSE;
+}
+
+static void
+tab_size_to_cb (EphyEmbed *embed,
+ int width,
+ int height,
+ EphyWindow *window)
+{
+ EphyWindowPrivate *priv = window->priv;
+ GtkWidget *widget = GTK_WIDGET (window);
+ GtkWidget *embed_widget = GTK_WIDGET (embed);
+ GdkScreen *screen;
+ EphyTab *tab;
+ GdkRectangle rect;
+ int monitor;
+ int ww, wh, ew, eh, dw, dh;
+
+ LOG ("tab_size_to_cb window %p embed %p width %d height %d", window, embed, width, height);
+
+ tab = ephy_tab_for_embed (embed);
+ g_return_if_fail (tab != NULL);
+
+ /* FIXME: allow sizing also for non-popup single-tab windows? */
+ if (tab != ephy_window_get_active_tab (window) || !priv->is_popup) return;
+
+ /* contrain size so that the window will be fully contained within the screen */
+ screen = gtk_widget_get_screen (widget);
+ monitor = gdk_screen_get_monitor_at_window (screen, widget->window);
+ gdk_screen_get_monitor_geometry (screen, monitor, &rect);
+ /* FIXME: get and subtract the panel size */
+
+ gtk_window_get_size (GTK_WINDOW (window), &ww, &wh);
+
+ ew = embed_widget->allocation.width;
+ eh = embed_widget->allocation.height;
+
+ /* This should approximate the chrome extent */
+ dw = ww - ew; dw = MAX (dw, 0); dw = MIN (dw, rect.width - 1);
+ dh = wh - eh; dh = MAX (dh, 0); dh = MIN (dh, rect.height - 1);
+
+ width = MIN (rect.width - dw, width);
+ height = MIN (rect.height - dh, height);
+
+ /* FIXME: move window if this will place it partially outside the screen rect? */
+
+ gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+ ephy_tab_set_size (tab, width, height);
+
+ if (priv->idle_resize_handler == 0)
+ {
+ priv->idle_resize_handler =
+ g_idle_add ((GSourceFunc) let_me_resize_hack, window);
+ }
+}
+
static void
ephy_window_set_active_tab (EphyWindow *window, EphyTab *new_tab)
{
@@ -1890,47 +1975,48 @@ ephy_window_set_active_tab (EphyWindow *window, EphyTab *new_tab)
if (old_tab != NULL)
{
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_address),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_document_type),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_icon),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_load_progress),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_load_status),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_message),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_navigation),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_security),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_popup_windows),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_popups_allowed),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_title),
window);
- g_signal_handlers_disconnect_by_func (G_OBJECT (old_tab),
+ g_signal_handlers_disconnect_by_func (old_tab,
G_CALLBACK (sync_tab_zoom),
window);
embed = ephy_tab_get_embed (old_tab);
- g_signal_handlers_disconnect_by_func (G_OBJECT (embed),
- G_CALLBACK (tab_context_menu_cb),
- window);
+ g_signal_handlers_disconnect_by_func
+ (embed, G_CALLBACK (tab_context_menu_cb), window);
+ g_signal_handlers_disconnect_by_func
+ (embed, G_CALLBACK (tab_size_to_cb), window);
}
window->priv->active_tab = new_tab;
@@ -1950,59 +2036,50 @@ ephy_window_set_active_tab (EphyWindow *window, EphyTab *new_tab)
sync_tab_title (new_tab, NULL, window);
sync_tab_zoom (new_tab, NULL, window);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::address",
+ g_signal_connect_object (new_tab, "notify::address",
G_CALLBACK (sync_tab_address),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::document-type",
+ g_signal_connect_object (new_tab, "notify::document-type",
G_CALLBACK (sync_tab_document_type),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::icon",
+ g_signal_connect_object (new_tab, "notify::icon",
G_CALLBACK (sync_tab_icon),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::load-progress",
+ g_signal_connect_object (new_tab, "notify::load-progress",
G_CALLBACK (sync_tab_load_progress),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::load-status",
+ g_signal_connect_object (new_tab, "notify::load-status",
G_CALLBACK (sync_tab_load_status),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::message",
+ g_signal_connect_object (new_tab, "notify::message",
G_CALLBACK (sync_tab_message),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::navigation",
+ g_signal_connect_object (new_tab, "notify::navigation",
G_CALLBACK (sync_tab_navigation),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::security-level",
+ g_signal_connect_object (new_tab, "notify::security-level",
G_CALLBACK (sync_tab_security),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::hidden-popup-count",
+ g_signal_connect_object (new_tab, "notify::hidden-popup-count",
G_CALLBACK (sync_tab_popup_windows),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::popups-allowed",
+ g_signal_connect_object (new_tab, "notify::popups-allowed",
G_CALLBACK (sync_tab_popups_allowed),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::title",
+ g_signal_connect_object (new_tab, "notify::title",
G_CALLBACK (sync_tab_title),
window, 0);
- g_signal_connect_object (G_OBJECT (new_tab),
- "notify::zoom",
+ g_signal_connect_object (new_tab, "notify::zoom",
G_CALLBACK (sync_tab_zoom),
window, 0);
embed = ephy_tab_get_embed (new_tab);
- g_signal_connect_object (embed, "ge_context_menu",
+ g_signal_connect_object (embed, "ge-context-menu",
G_CALLBACK (tab_context_menu_cb),
window, G_CONNECT_AFTER);
+ g_signal_connect_object (embed, "size-to",
+ G_CALLBACK (tab_size_to_cb),
+ window, 0);
g_object_notify (G_OBJECT (window), "active-tab");
}
@@ -2308,11 +2385,22 @@ ephy_window_set_chrome (EphyWindow *window, EphyEmbedChrome mask)
window->priv->chrome = chrome_mask;
- sync_chromes_visibility (window);
update_chromes_actions (window);
}
static void
+ephy_window_set_is_popup (EphyWindow *window,
+ gboolean is_popup)
+{
+ EphyWindowPrivate *priv = window->priv;
+
+ priv->is_popup = is_popup;
+ ephy_notebook_set_dnd_enabled (EPHY_NOTEBOOK (priv->notebook), !is_popup);
+
+ g_object_notify (G_OBJECT (window), "is-popup");
+}
+
+static void
ephy_window_dispose (GObject *object)
{
EphyWindow *window = EPHY_WINDOW (object);
@@ -2353,6 +2441,12 @@ ephy_window_dispose (GObject *object)
eel_gconf_notification_remove (priv->browse_with_caret_notifier_id);
eel_gconf_notification_remove (priv->allow_popups_notifier_id);
+ if (priv->idle_resize_handler != 0)
+ {
+ g_source_remove (priv->idle_resize_handler);
+ priv->idle_resize_handler = 0;
+ }
+
if (priv->find_dialog)
{
g_object_unref (G_OBJECT (priv->find_dialog));
@@ -2408,6 +2502,9 @@ ephy_window_set_property (GObject *object,
case PROP_PPV_MODE:
ephy_window_set_print_preview (window, g_value_get_boolean (value));
break;
+ case PROP_SINGLE_TAB_MODE:
+ ephy_window_set_is_popup (window, g_value_get_boolean (value));
+ break;
}
}
@@ -2430,6 +2527,9 @@ ephy_window_get_property (GObject *object,
case PROP_PPV_MODE:
g_value_set_boolean (value, window->priv->ppv_mode);
break;
+ case PROP_SINGLE_TAB_MODE:
+ g_value_set_boolean (value, window->priv->is_popup);
+ break;
}
}
@@ -2477,6 +2577,7 @@ ephy_window_class_init (EphyWindowClass *klass)
parent_class = g_type_class_peek_parent (klass);
+ object_class->constructor = ephy_window_constructor;
object_class->dispose = ephy_window_dispose;
object_class->finalize = ephy_window_finalize;
object_class->get_property = ephy_window_get_property;
@@ -2513,6 +2614,15 @@ ephy_window_class_init (EphyWindowClass *klass)
FALSE,
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_SINGLE_TAB_MODE,
+ g_param_spec_boolean ("is-popup",
+ "Single Tab Mode",
+ "Whether the window is in single tab mode",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
g_type_class_add_private (object_class, sizeof (EphyWindowPrivate));
}
@@ -2737,8 +2847,6 @@ ephy_window_init (EphyWindow *window)
GTK_WIDGET (window->priv->toolbar),
FALSE, FALSE, 0);
- update_actions_sensitivity (window);
-
/* Once the window is sufficiently created let the extensions attach to it */
manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell));
ephy_extension_attach_window (manager, window);
@@ -2819,6 +2927,25 @@ ephy_window_init (EphyWindow *window)
init_menu_updaters (window);
}
+static GObject *
+ephy_window_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ EphyWindow *window;
+
+ object = parent_class->constructor (type, n_construct_properties,
+ construct_params);
+
+ window = EPHY_WINDOW (object);
+
+ update_actions_sensitivity (window);
+ sync_chromes_visibility (window);
+
+ return object;
+}
+
static void
ephy_window_finalize (GObject *object)
{
@@ -2846,16 +2973,19 @@ ephy_window_new (void)
/**
* ephy_window_new_with_chrome:
* @chrome: an #EphyEmbedChrome
+ * @is_popup: whether the new window is a popup window
*
* Identical to ephy_window_new(), but allows you to specify a chrome.
*
* Return value: a new #EphyWindow
**/
EphyWindow *
-ephy_window_new_with_chrome (EphyEmbedChrome chrome)
+ephy_window_new_with_chrome (EphyEmbedChrome chrome,
+ gboolean is_popup)
{
return EPHY_WINDOW (g_object_new (EPHY_TYPE_WINDOW,
"chrome", chrome,
+ "is-popup", is_popup,
NULL));
}
@@ -2878,7 +3008,6 @@ ephy_window_set_print_preview (EphyWindow *window, gboolean enabled)
window->priv->ppv_mode = enabled;
sync_chromes_visibility (window);
- ephy_notebook_set_show_tabs (EPHY_NOTEBOOK (window->priv->notebook), !enabled);
if (enabled)
{
@@ -2998,6 +3127,8 @@ ephy_window_add_tab (EphyWindow *window,
g_return_if_fail (EPHY_IS_WINDOW (window));
g_return_if_fail (EPHY_IS_TAB (tab));
+ g_return_if_fail (!window->priv->is_popup ||
+ gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook)) < 1);
widget = GTK_WIDGET(ephy_tab_get_embed (tab));
@@ -3111,8 +3242,9 @@ static void
ephy_window_show (GtkWidget *widget)
{
EphyWindow *window = EPHY_WINDOW(widget);
+ EphyWindowPrivate *priv = window->priv;
- if (!window->priv->has_size)
+ if (!priv->has_size)
{
EphyTab *tab;
int width, height;
@@ -3127,7 +3259,7 @@ ephy_window_show (GtkWidget *widget)
TRUE, EPHY_STATE_WINDOW_SAVE_SIZE);
}
- window->priv->has_size = TRUE;
+ priv->has_size = TRUE;
}
GTK_WIDGET_CLASS (parent_class)->show (widget);
@@ -3369,3 +3501,19 @@ ephy_window_view_popup_windows_cb (GtkAction *action,
g_object_set (G_OBJECT (tab), "popups-allowed", allow, NULL);
}
+
+/**
+ * ephy_window_get_is_popup:
+ * @window: an #EphyWindow
+ *
+ * Returns whether this window is a popup window.
+ *
+ * Return value: %TRUE if it is a popup window
+ **/
+gboolean
+ephy_window_get_is_popup (EphyWindow *window)
+{
+ g_return_val_if_fail (EPHY_IS_WINDOW (window), FALSE);
+
+ return window->priv->is_popup;
+}
diff --git a/src/ephy-window.h b/src/ephy-window.h
index cee6a297a..df0486c8f 100644
--- a/src/ephy-window.h
+++ b/src/ephy-window.h
@@ -58,7 +58,8 @@ GType ephy_window_get_type (void);
EphyWindow *ephy_window_new (void);
-EphyWindow *ephy_window_new_with_chrome (EphyEmbedChrome chrome);
+EphyWindow *ephy_window_new_with_chrome (EphyEmbedChrome chrome,
+ gboolean is_popup);
void ephy_window_set_print_preview (EphyWindow *window,
gboolean enabled);
@@ -100,6 +101,8 @@ GList *ephy_window_get_tabs (EphyWindow *window);
void ephy_window_find (EphyWindow *window);
+gboolean ephy_window_get_is_popup (EphyWindow *window);
+
G_END_DECLS
#endif