-
User styles are CSS Cascading Style sheets that are loaded locally and applied on top of web pages, similar to User scripts, in order to add or alter functionality and also fix bugs.
diff --git a/docs/api/wscript_build b/docs/api/wscript_build
index fdcecb50..df546b18 100644
--- a/docs/api/wscript_build
+++ b/docs/api/wscript_build
@@ -6,18 +6,20 @@ import pproc as subprocess
import os
import Utils
+blddir = '_build' # recognized by ack
+
for module in ('midori', 'katze'):
try:
- if not os.access ('_build_', os.F_OK):
- Utils.check_dir ('_build_')
- if not os.access ('_build_/docs', os.F_OK):
- Utils.check_dir ('_build_/docs')
- if not os.access ('_build_/docs/api', os.F_OK):
- Utils.check_dir ('_build_/docs/api')
+ if not os.access (blddir, os.F_OK):
+ Utils.check_dir (blddir)
+ if not os.access (blddir + '/docs', os.F_OK):
+ Utils.check_dir (blddir + '/docs')
+ if not os.access (blddir + '/docs/api', os.F_OK):
+ Utils.check_dir (blddir + '/docs/api')
subprocess.call (['gtkdoc-scan', '--module=' + module,
- '--source-dir=' + module, '--output-dir=_build_/docs/api/' + module,
+ '--source-dir=' + module, '--output-dir=' + blddir + '/docs/api/' + module,
'--rebuild-sections', '--rebuild-types'])
- os.chdir ('_build_/docs/api/' + module)
+ os.chdir (blddir + '/docs/api/' + module)
subprocess.call (['gtkdoc-mktmpl', '--module=' + module,
'--output-dir=.' + module])
subprocess.call (['gtkdoc-mkdb', '--module=' + module,
diff --git a/extensions/adblock.c b/extensions/adblock.c
index 5f590de5..2b35fa53 100644
--- a/extensions/adblock.c
+++ b/extensions/adblock.c
@@ -39,6 +39,7 @@ static GHashTable* keys = NULL;
static GHashTable* optslist = NULL;
static GHashTable* urlcache = NULL;
static GHashTable* blockcssprivate = NULL;
+static GHashTable* navigationwhitelist = NULL;
static GString* blockcss = NULL;
#ifdef G_ENABLE_DEBUG
static guint debug;
@@ -127,6 +128,8 @@ adblock_destroy_db ()
urlcache = NULL;
g_hash_table_destroy (blockcssprivate);
blockcssprivate = NULL;
+ g_hash_table_destroy (navigationwhitelist);
+ navigationwhitelist = NULL;
}
static void
@@ -147,6 +150,9 @@ adblock_init_db ()
blockcssprivate = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)g_free);
+ navigationwhitelist = g_hash_table_new_full (g_direct_hash, g_str_equal,
+ NULL,
+ (GDestroyNotify)g_free);
if (blockcss && blockcss->len > 0)
g_string_free (blockcss, TRUE);
@@ -779,6 +785,23 @@ adblock_prepare_urihider_js (GList* uris)
return g_string_free (js, FALSE);
}
+static gboolean
+adblock_navigation_policy_decision_requested_cb (WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ WebKitNetworkRequest* request,
+ WebKitWebNavigationAction* action,
+ WebKitWebPolicyDecision* decision,
+ MidoriView* view)
+{
+ if (web_frame == webkit_web_view_get_main_frame (web_view))
+ {
+ const gchar* req_uri = webkit_network_request_get_uri (request);
+ g_hash_table_replace (navigationwhitelist, web_view, g_strdup (req_uri));
+ }
+ return false;
+}
+
+
static void
adblock_resource_request_starting_cb (WebKitWebView* web_view,
WebKitWebFrame* web_frame,
@@ -798,6 +821,10 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
return;
req_uri = webkit_network_request_get_uri (request);
+
+ if (!g_strcmp0 (req_uri, g_hash_table_lookup (navigationwhitelist, web_view)))
+ return;
+
if (!midori_uri_is_http (req_uri)
|| g_str_has_suffix (req_uri, "favicon.ico"))
return;
@@ -806,6 +833,15 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
if (!(msg && !g_strcmp0 (msg->method, "GET")))
return;
+ if (response != NULL) /* request is caused by redirect */
+ {
+ if (web_frame == webkit_web_view_get_main_frame (web_view))
+ {
+ g_hash_table_replace (navigationwhitelist, web_view, g_strdup (req_uri));
+ return;
+ }
+ }
+
#ifdef G_ENABLE_DEBUG
if (debug == 2)
g_test_timer_start ();
@@ -877,16 +913,16 @@ adblock_custom_block_image_cb (GtkWidget* widget,
custom_list = g_build_filename (midori_extension_get_config_dir (extension),
CUSTOM_LIST_NAME, NULL);
- if (!(list = g_fopen (custom_list, "a+")))
+ katze_mkdir_with_parents (midori_extension_get_config_dir (extension), 0700);
+ if ((list = g_fopen (custom_list, "a+")))
{
- g_free (custom_list);
- return;
+ g_fprintf (list, "%s\n", gtk_entry_get_text (GTK_ENTRY (entry)));
+ fclose (list);
+ adblock_reload_rules (extension, TRUE);
+ g_debug ("%s: Updated custom list\n", G_STRFUNC);
}
-
- g_fprintf (list, "%s\n", gtk_entry_get_text (GTK_ENTRY (entry)));
- fclose (list);
- adblock_reload_rules (extension, TRUE);
-
+ else
+ g_debug ("%s: Failed to open custom list %s\n", G_STRFUNC, custom_list);
g_free (custom_list);
gtk_widget_destroy (dialog);
}
@@ -983,6 +1019,8 @@ adblock_add_tab_cb (MidoriBrowser* browser,
g_signal_connect_after (web_view, "populate-popup",
G_CALLBACK (adblock_populate_popup_cb), extension);
+ g_signal_connect (web_view, "navigation-policy-decision-requested",
+ G_CALLBACK (adblock_navigation_policy_decision_requested_cb), view);
g_signal_connect (web_view, "resource-request-starting",
G_CALLBACK (adblock_resource_request_starting_cb), image);
g_signal_connect (web_view, "load-finished",
@@ -990,16 +1028,17 @@ adblock_add_tab_cb (MidoriBrowser* browser,
}
static void
-adblock_deactivate_cb (MidoriExtension* extension,
- MidoriBrowser* browser);
+adblock_remove_tab_cb (MidoriBrowser* browser,
+ MidoriView* view,
+ MidoriExtension* extension)
+{
+ GtkWidget* web_view = midori_view_get_web_view (view);
+ g_hash_table_remove (navigationwhitelist, web_view);
+}
static void
-adblock_add_tab_foreach_cb (MidoriView* view,
- MidoriBrowser* browser,
- MidoriExtension* extension)
-{
- adblock_add_tab_cb (browser, view, extension);
-}
+adblock_deactivate_cb (MidoriExtension* extension,
+ MidoriBrowser* browser);
static void
adblock_app_add_browser_cb (MidoriApp* app,
@@ -1008,6 +1047,8 @@ adblock_app_add_browser_cb (MidoriApp* app,
{
GtkWidget* statusbar;
GtkWidget* image;
+ GtkWidget* view;
+ gint i;
statusbar = katze_object_get_object (browser, "statusbar");
image = NULL;
@@ -1017,10 +1058,14 @@ adblock_app_add_browser_cb (MidoriApp* app,
g_object_set_data_full (G_OBJECT (browser), "status-image", image,
(GDestroyNotify)gtk_widget_destroy);
- midori_browser_foreach (browser,
- (GtkCallback)adblock_add_tab_foreach_cb, extension);
+ i = 0;
+ while((view = midori_browser_get_nth_tab(browser, i++)))
+ adblock_add_tab_cb (browser, MIDORI_VIEW (view), extension);
+
g_signal_connect (browser, "add-tab",
G_CALLBACK (adblock_add_tab_cb), extension);
+ g_signal_connect (browser, "remove-tab",
+ G_CALLBACK (adblock_remove_tab_cb), extension);
g_signal_connect (extension, "open-preferences",
G_CALLBACK (adblock_open_preferences_cb), extension);
g_signal_connect (extension, "deactivate",
@@ -1284,7 +1329,7 @@ adblock_frame_add_private (const gchar* line,
/* Ignore Firefox-specific option */
if (!g_strcmp0 (domain, "~pregecko2"))
continue;
- /* strip ~ from domain */
+ /* FIXME: ~ should negate match */
if (domain[0] == '~')
domain++;
adblock_update_css_hash (g_strstrip (domain), data[1]);
@@ -1301,6 +1346,88 @@ adblock_frame_add_private (const gchar* line,
static gchar*
adblock_parse_line (gchar* line)
{
+ /*
+ * AdblockPlus rule reference based on http://adblockplus.org/en/filters
+ * Block URL:
+ * http://example.com/ads/banner123.gif
+ * http://example.com/ads/banner*.gif
+ * http://example.com/ads/*
+ * Partial match for "ad":
+ * *ad*
+ * ad
+ * Block example.com/annoyingflash.swf but not example.com/swf/:
+ * swf|
+ * Block bad.example/banner.gif but not good.example/analyze?http://bad.example:
+ * |http://baddomain.example/
+ * Block http(s) example.com but not badexample.com or good.example/analyze?http://bad.example:
+ * ||example.com/banner.gif
+ * Block example.com/ and example.com:8000/ but not example.com.ar/:
+ * http://example.com^
+ * A ^ matches anything that isn't A-Za-z0-0_-.%
+ * Block example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5:
+ * ^example.com^
+ * ^%D1%82%D0%B5^
+ * ^foo.bar^
+ * TODO: ^ is partially supported by Midori
+ * Block banner123 and banner321 with a regex:
+ * /banner\d+/
+ * Never block URIs with "advice":
+ * @@advice
+ * No blocking at all:
+ * @@http://example.com
+ * @@|http://example.com
+ * TODO: @@ is currently ignored by Midori.
+ * Element hiding by class:
+ * ##textad
+ * ##div.textad
+ * Element hiding by id:
+ * ##div#sponsorad
+ * ##*#sponsorad
+ * Match example.com/ and something.example.com/ but not example.org/
+ * example.com##*.sponsor
+ * Match multiple domains:
+ * domain1.example,domain2.example,domain3.example##*.sponsor
+ * Match on any domain but "example.com":
+ * ~example.com##*.sponsor
+ * Match on "example.com" except "foo.example.com":
+ * example.com,~foo.example.com##*.sponsor
+ * By design rules only apply to full domain names:
+ * "domain" is NOT equal to "domain.example,domain.test."
+ * In Firefox rules can apply to browser UI:
+ * browser##menuitem#javascriptConsole will hide the Console menuitem
+ * Hide tables with width attribute 80%:
+ * ##table[width="80%"]
+ * Hide all div with title attribute containing "adv":
+ * ##div[title*="adv"]
+ * Hide div with title starting with "adv" and ending with "ert":
+ * ##div[title^="adv"][title$="ert"]
+ * Match tables with width attribute 80% and bgcolor attribute white:
+ * table[width="80%"][bgcolor="white"]
+ * TODO: [] is currently ignored by Midori
+ * Hide anything following div with class "adheader":
+ * ##div.adheader + *
+ * Old CSS element hiding syntax, officially deprecated:
+ * #div(id=foo)
+ * Match anything but "example.com"
+ * ~example.com##*.sponsor
+ * TODO: ~ is currently ignored by Midori
+ * Match "example.com" domain except "foo.example.com":
+ * example.com,~foo.example.com##*.sponsor
+ * ! Comment
+ * Supported options after a trailing $:
+ * domain,third-party,~pregecko2
+ * Official options (not all supported by Midori):
+ * script,image,stylesheet,object,xmlhttprequest,object-subrequest,
+ * subdocument,document,elemhide,popup,third-party,sitekey,match-case
+ * collapse,donottrack,pregecko2
+ * Deprecated:
+ * background,xbl,ping,dtd
+ * Inverse options:
+ * ~script,~image,~stylesheet,~object,~xmlhttprequest,~collapse,
+ * ~object-subrequest,~subdocument,~document,~elemhide,~third-party,
+ * ~pregecko2
+ **/
+
/* Skip invalid, empty and comment lines */
if (!(line && line[0] != ' ' && line[0] != '!' && line[0]))
return NULL;
@@ -1376,8 +1503,6 @@ adblock_deactivate_tabs (MidoriView* view,
GtkWidget* web_view = midori_view_get_web_view (view);
GtkWidget* image = g_object_get_data (G_OBJECT (browser), "status-image");
- g_signal_handlers_disconnect_by_func (
- browser, adblock_add_tab_cb, extension);
g_signal_handlers_disconnect_by_func (
web_view, adblock_window_object_cleared_cb, 0);
g_signal_handlers_disconnect_by_func (
@@ -1386,12 +1511,16 @@ adblock_deactivate_tabs (MidoriView* view,
web_view, adblock_resource_request_starting_cb, image);
g_signal_handlers_disconnect_by_func (
web_view, adblock_load_finished_cb, image);
+ g_signal_handlers_disconnect_by_func (
+ web_view, adblock_navigation_policy_decision_requested_cb, view);
}
static void
adblock_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser)
{
+ gint i;
+ GtkWidget* view;
MidoriApp* app = midori_extension_get_app (extension);
MidoriWebSettings* settings = katze_object_get_object (app, "settings");
@@ -1403,7 +1532,12 @@ adblock_deactivate_cb (MidoriExtension* extension,
app, adblock_app_add_browser_cb, extension);
g_signal_handlers_disconnect_by_func (
browser, adblock_add_tab_cb, extension);
- midori_browser_foreach (browser, (GtkCallback)adblock_deactivate_tabs, browser);
+ g_signal_handlers_disconnect_by_func (
+ browser, adblock_remove_tab_cb, extension);
+
+ i = 0;
+ while((view = midori_browser_get_nth_tab(browser, i++)))
+ adblock_deactivate_tabs (MIDORI_VIEW (view), browser, extension);
adblock_destroy_db ();
midori_web_settings_remove_style (settings, "adblock-blockcss");
diff --git a/extensions/external-download-manager.vala b/extensions/external-download-manager.vala
new file mode 100644
index 00000000..f7266f7a
--- /dev/null
+++ b/extensions/external-download-manager.vala
@@ -0,0 +1,218 @@
+/*
+ Copyright (C) 2012 André Stösel
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+using Gtk;
+using Soup;
+using Katze;
+using Midori;
+using WebKit;
+
+namespace EDM {
+ [DBus (name = "net.launchpad.steadyflow.App")]
+ interface SteadyflowInterface : GLib.Object {
+ public abstract void AddFile (string url) throws IOError;
+ }
+
+ private class DownloadRequest : GLib.Object {
+ public string uri;
+ public string auth;
+ public string referer;
+ public string? cookie_header;
+ }
+
+ internal Manager manager;
+
+ private class Manager : GLib.Object {
+ private CookieJar cookie_jar;
+ private GLib.PtrArray download_managers = new GLib.PtrArray ();
+
+ public bool download_requested (Midori.View view, WebKit.Download download) {
+ if (download.get_data ("save-as-download") == null
+ && download.get_data ("open-download") == null) {
+ var dlReq = new DownloadRequest ();
+ dlReq.uri = download.get_uri ();
+
+ var request = download.get_network_request ();
+ var message = request.get_message ();
+ weak MessageHeaders headers = message.request_headers;
+
+ dlReq.auth = headers.get ("Authorization");
+ dlReq.referer = headers.get ("Referer");
+ dlReq.cookie_header = this.cookie_jar.get_cookies (new Soup.URI (dlReq.uri), true);
+
+ for (var i = 0 ; i < download_managers.len; i++) {
+ var dm = download_managers.index (i) as ExternalDownloadManager;
+ if (dm.download (dlReq))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void tab_added (Midori.Browser browser, Midori.View view) {
+ view.download_requested.connect (download_requested);
+ }
+
+ public void tab_removed (Midori.Browser browser, Midori.View view) {
+ view.download_requested.disconnect(download_requested);
+ }
+
+ public void browser_added (Midori.Browser browser) {
+ foreach (var tab in browser.get_tabs ())
+ tab_added (browser, tab);
+ browser.add_tab.connect (tab_added);
+ browser.remove_tab.connect (tab_removed);
+ }
+
+ public void browser_removed (Midori.Browser browser) {
+ foreach (var tab in browser.get_tabs ())
+ tab_removed (browser, tab);
+ browser.add_tab.disconnect (tab_added);
+ browser.remove_tab.disconnect (tab_removed);
+ }
+
+ public void activated (Midori.Extension extension, Midori.App app) {
+ this.download_managers.add (extension);
+ if (this.download_managers.len == 1) {
+ foreach (var browser in app.get_browsers ())
+ browser_added (browser);
+ app.add_browser.connect (browser_added);
+ }
+ }
+
+ public void deactivated (Midori.Extension extension) {
+ this.download_managers.remove (extension);
+ if (this.download_managers.len == 0) {
+ var app = extension.get_app ();
+ foreach (var browser in app.get_browsers ())
+ browser_removed (browser);
+ app.add_browser.disconnect (browser_added);
+ }
+ }
+
+ construct {
+ var session = WebKit.get_default_session ();
+ this.cookie_jar = session.get_feature (typeof (CookieJar)) as CookieJar;
+ }
+ }
+
+ private abstract class ExternalDownloadManager : Midori.Extension {
+ public void activated (Midori.App app) {
+ manager.activated (this, app);
+ }
+
+ public void deactivated () {
+ manager.deactivated (this);
+ }
+
+ public void handle_exception (GLib.Error error) {
+ string ext_name;
+ this.get ("name",out ext_name);
+ var dialog = new MessageDialog (null, DialogFlags.MODAL,
+ MessageType.ERROR, ButtonsType.CLOSE,
+ _("An error occurred when attempting to download a file with the following plugin:\n" +
+ "%s\n\n" +
+ "Error:\n%s\n\n" +
+ "Carry on without this plugin."
+ ),
+ ext_name, error.message);
+ dialog.response.connect ((a) => { dialog.destroy (); });
+ dialog.run ();
+ }
+
+ public abstract bool download (DownloadRequest dlReq);
+ }
+
+ private class Aria2 : ExternalDownloadManager {
+ public override bool download (DownloadRequest dlReq) {
+ var url = value_array_new ();
+ value_array_insert (url, 0, typeof (string), dlReq.uri);
+
+ GLib.HashTable options = value_hash_new ();
+ var referer = new GLib.Value (typeof (string));
+ referer.set_string (dlReq.referer);
+ options.insert ("referer", referer);
+
+ var headers = value_array_new ();
+ if (dlReq.cookie_header != null) {
+ value_array_insert (headers, 0, typeof (string), "Cookie: %s".printf(dlReq.cookie_header));
+ }
+
+ if (headers.n_values > 0)
+ options.insert ("header", headers);
+
+ var message = XMLRPC.request_new ("http://127.0.0.1:6800/rpc",
+ "aria2.addUri",
+ typeof (ValueArray), url,
+ typeof(HashTable), options);
+ var session = new SessionSync ();
+ session.send_message (message);
+
+ try {
+ Value v;
+ XMLRPC.parse_method_response ((string) message.response_body.flatten ().data, -1, out v);
+ return true;
+ } catch (Error e) {
+ this.handle_exception (e);
+ }
+
+ return false;
+ }
+
+ internal Aria2 () {
+ GLib.Object (name: _("External Download Manager - Aria2"),
+ description: _("Download files with Aria2"),
+ version: "0.1" + Midori.VERSION_SUFFIX,
+ authors: "André Stösel ",
+ key: "aria2");
+
+ this.activate.connect (activated);
+ this.deactivate.connect (deactivated);
+ }
+ }
+
+ private class SteadyFlow : ExternalDownloadManager {
+ public override bool download (DownloadRequest dlReq) {
+ try {
+ SteadyflowInterface dm = Bus.get_proxy_sync (
+ BusType.SESSION,
+ "net.launchpad.steadyflow.App",
+ "/net/launchpad/steadyflow/app");
+ dm.AddFile (dlReq.uri);
+ return true;
+ } catch (Error e) {
+ this.handle_exception (e);
+ }
+ return false;
+ }
+
+ internal SteadyFlow () {
+ GLib.Object (name: _("External Download Manager - SteadyFlow"),
+ description: _("Download files with SteadyFlow"),
+ version: "0.1" + Midori.VERSION_SUFFIX,
+ authors: "André Stösel ",
+ key: "steadyflow");
+
+ this.activate.connect (activated);
+ this.deactivate.connect (deactivated);
+ }
+ }
+}
+
+public Katze.Array extension_init () {
+ EDM.manager = new EDM.Manager();
+
+ var extensions = new Katze.Array( typeof (Midori.Extension));
+ extensions.add_item (new EDM.Aria2 ());
+ extensions.add_item (new EDM.SteadyFlow ());
+ return extensions;
+}
+
diff --git a/extensions/formhistory/formhistory.c b/extensions/formhistory/formhistory.c
index 90d61858..db5a2344 100644
--- a/extensions/formhistory/formhistory.c
+++ b/extensions/formhistory/formhistory.c
@@ -193,7 +193,7 @@ formhistory_navigation_decision_cb (WebKitWebView* web_view,
The field separator is "|||" */
const gchar* script = "function dumpForm (inputs) {"
" var out = '';"
- " for (i=0;i
+ This file is licensed under the terms of the expat license, see the file EXPAT. */
+
+[CCode (cprefix = "Katze", lower_case_cprefix = "katze_")]
+namespace Katze {
+ public class Array : GLib.Object {
+ public Array (GLib.Type type);
+ public void add_item (GLib.Object item);
+ }
+}
+
diff --git a/midori/main.c b/midori/main.c
index 726279ad..2ec55990 100644
--- a/midori/main.c
+++ b/midori/main.c
@@ -264,8 +264,24 @@ settings_save_to_file (MidoriWebSettings* settings,
{
KATZE_ARRAY_FOREACH_ITEM (extension, extensions)
if (midori_extension_is_active (extension))
- g_key_file_set_boolean (key_file, "extensions",
- g_object_get_data (G_OBJECT (extension), "filename"), TRUE);
+ {
+ const gchar* filename = g_object_get_data (
+ G_OBJECT (extension), "filename");
+
+ gchar* key;
+ gchar* term;
+
+ key = katze_object_get_string (extension, "key");
+ if (key && *key)
+ term = g_strdup_printf ("%s/%s", filename, key);
+ else
+ term = g_strdup (filename);
+
+ g_key_file_set_boolean (key_file, "extensions", term, TRUE);
+
+ g_free (key);
+ g_free (term);
+ }
g_object_unref (extensions);
}
else if ((_extensions = g_object_get_data (G_OBJECT (app), "extensions")))
@@ -441,9 +457,12 @@ midori_history_initialize (KatzeArray* array,
return FALSE;
}
+ if (sqlite3_exec (db,
+ "PRAGMA journal_mode = WAL; PRAGMA cache_size = 32100;",
+ NULL, NULL, errmsg) != SQLITE_OK)
+ sqlite3_exec (db, "PRAGMA journal_mode = TRUNCATE;", NULL, NULL, errmsg);
sqlite3_exec (db,
- /* "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY" */
- "PRAGMA count_changes = OFF; PRAGMA journal_mode = TRUNCATE;",
+ "PRAGMA synchronous = NORMAL; PRAGMA temp_store = MEMORY;",
NULL, NULL, errmsg);
if (*errmsg)
{
@@ -964,7 +983,7 @@ midori_soup_session_settings_accept_language_cb (SoupSession* session,
if (stripped_uri != NULL)
{
gchar* stripped_referer;
- soup_uri_set_path (stripped_uri, NULL);
+ soup_uri_set_path (stripped_uri, "");
soup_uri_set_query (stripped_uri, NULL);
stripped_referer = soup_uri_to_string (stripped_uri, FALSE);
soup_uri_free (stripped_uri);
@@ -1226,6 +1245,46 @@ midori_load_soup_session_full (gpointer settings)
return FALSE;
}
+static void
+midori_load_extension (MidoriApp* app,
+ KatzeArray* extensions,
+ gchar** active_extensions,
+ MidoriExtension* extension,
+ const gchar* filename)
+{
+ /* Signal that we want the extension to load and save */
+ g_object_set_data_full (G_OBJECT (extension), "filename",
+ g_strdup (filename), g_free);
+ if (midori_extension_is_prepared (extension))
+ midori_extension_get_config_dir (extension);
+
+ katze_array_add_item (extensions, extension);
+ if (active_extensions)
+ {
+ guint i = 0;
+ gchar* key;
+ gchar* name;
+ gchar* term;
+
+ key = katze_object_get_string (extension, "key");
+ if (key && *key)
+ term = g_strdup_printf ("%s/%s", filename, key);
+ else
+ term = g_strdup (filename);
+
+ while ((name = active_extensions[i++]))
+ if (!g_strcmp0 (term, name))
+ g_signal_emit_by_name (extension, "activate", app);
+
+ g_free (key);
+ g_free (term);
+ }
+ g_signal_connect_after (extension, "activate",
+ G_CALLBACK (extension_activate_cb), app);
+ g_signal_connect_after (extension, "deactivate",
+ G_CALLBACK (extension_activate_cb), app);
+}
+
static gboolean
midori_load_extensions (gpointer data)
{
@@ -1257,9 +1316,9 @@ midori_load_extensions (gpointer data)
{
gchar* fullname;
GModule* module;
- typedef MidoriExtension* (*extension_init_func)(void);
+ typedef GObject* (*extension_init_func)(void);
extension_init_func extension_init;
- MidoriExtension* extension = NULL;
+ GObject* extension = NULL;
/* Ignore files which don't have the correct suffix */
if (!g_str_has_suffix (filename, G_MODULE_SUFFIX))
@@ -1275,11 +1334,22 @@ midori_load_extensions (gpointer data)
extension = extension_init ();
if (extension != NULL)
{
- /* Signal that we want the extension to load and save */
- g_object_set_data_full (G_OBJECT (extension), "filename",
- g_strdup (filename), g_free);
- if (midori_extension_is_prepared (extension))
- midori_extension_get_config_dir (extension);
+ if (MIDORI_IS_EXTENSION (extension))
+ midori_load_extension (app, extensions,
+ active_extensions,
+ MIDORI_EXTENSION (extension), filename);
+ else if (KATZE_IS_ARRAY (extension))
+ {
+ MidoriExtension* extension_item;
+ KATZE_ARRAY_FOREACH_ITEM (extension_item, KATZE_ARRAY (extension))
+ {
+ if (MIDORI_IS_EXTENSION (extension_item))
+ midori_load_extension (app, extensions,
+ active_extensions, extension_item,
+ filename);
+ }
+ }
+
}
}
@@ -1294,20 +1364,8 @@ midori_load_extensions (gpointer data)
"description", g_module_error (),
NULL);
g_warning ("%s", g_module_error ());
+ katze_array_add_item (extensions, extension);
}
- katze_array_add_item (extensions, extension);
- if (active_extensions)
- {
- guint i = 0;
- gchar* name;
- while ((name = active_extensions[i++]))
- if (!g_strcmp0 (filename, name))
- g_signal_emit_by_name (extension, "activate", app);
- }
- g_signal_connect_after (extension, "activate",
- G_CALLBACK (extension_activate_cb), app);
- g_signal_connect_after (extension, "deactivate",
- G_CALLBACK (extension_activate_cb), app);
g_object_unref (extension);
}
g_dir_close (extension_dir);
@@ -1515,7 +1573,8 @@ midori_prepare_uri (const gchar *uri)
if (g_str_has_prefix(uri, "javascript:"))
return NULL;
- else if (g_file_test (uri, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+ else if (g_file_test (uri, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)
+ && !g_path_is_absolute (uri))
{
gchar* current_dir = g_get_current_dir ();
uri_ready = g_strconcat ("file://", current_dir,
@@ -1572,7 +1631,7 @@ speeddial_new_from_file (const gchar* config,
g_string_append_len (script, json_content, json_length);
g_string_append (script, "); "
"var keyfile = '';"
- "for (i in json['shortcuts']) {"
+ "for (var i in json['shortcuts']) {"
"var tile = json['shortcuts'][i];"
"keyfile += '[Dial ' + tile['id'].substring (1) + ']\\n'"
" + 'uri=' + tile['href'] + '\\n'"
@@ -1991,10 +2050,14 @@ main (int argc,
return 1;
}
+ /* Relative config path */
if (config && !g_path_is_absolute (config))
{
- g_critical (_("The specified configuration folder is invalid."));
- return 1;
+ gchar* old_config = config;
+ gchar* current_dir = g_get_current_dir ();
+ config = g_build_filename (current_dir, old_config, NULL);
+ g_free (current_dir);
+ g_free (old_config);
}
/* Private browsing, window title, default config folder */
@@ -2238,6 +2301,7 @@ main (int argc,
g_object_set (settings,
"show-menubar", FALSE,
"show-navigationbar", FALSE,
+ "always-show-tabbar", FALSE,
"toolbar-items", "Back,Forward,ReloadStop,Location,Homepage",
"show-statusbar", FALSE,
"enable-developer-extras", FALSE,
diff --git a/midori/midori-app.c b/midori/midori-app.c
index 46400944..84d50258 100644
--- a/midori/midori-app.c
+++ b/midori/midori-app.c
@@ -68,9 +68,6 @@ struct _MidoriApp
{
GObject parent_instance;
- MidoriBrowser* browser;
-
- gchar* name;
MidoriWebSettings* settings;
KatzeArray* bookmarks;
KatzeArray* trash;
@@ -80,6 +77,7 @@ struct _MidoriApp
KatzeArray* extensions;
KatzeArray* browsers;
+ MidoriBrowser* browser;
MidoriAppInstance instance;
#if !HAVE_HILDON || !HAVE_LIBNOTIFY
@@ -87,6 +85,8 @@ struct _MidoriApp
#endif
};
+static gchar* app_name = NULL;
+
struct _MidoriAppClass
{
GObjectClass parent_class;
@@ -718,29 +718,30 @@ midori_app_create_instance (MidoriApp* app)
GIOChannel* channel;
#endif
- if (!app->name)
+ if (!(display = gdk_display_get_default ()))
+ return MidoriAppInstanceNull;
+
{
#if HAVE_UNIQUE
const gchar* config = sokoke_set_config_dir (NULL);
gchar* name_hash;
name_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, config, -1);
- app->name = g_strconcat ("midori", "_", name_hash, NULL);
+ katze_assign (app_name, g_strconcat ("midori", "_", name_hash, NULL));
g_free (name_hash);
g_object_notify (G_OBJECT (app), "name");
#else
- app->name = g_strdup (PACKAGE_NAME);
+ katze_assign (app_name, g_strdup (PACKAGE_NAME));
#endif
}
- if (!(display = gdk_display_get_default ()))
- return MidoriAppInstanceNull;
-
display_name = g_strdup (gdk_display_get_name (display));
n = strlen (display_name);
for (i = 0; i < n; i++)
if (strchr (":.\\/", display_name[i]))
display_name[i] = '_';
- instance_name = g_strdup_printf ("de.twotoasts.%s_%s", app->name, display_name);
+ instance_name = g_strdup_printf ("de.twotoasts.%s_%s", app_name, display_name);
+ g_free (display_name);
+ katze_assign (app_name, instance_name);
#if HAVE_UNIQUE
instance = unique_app_new (instance_name, NULL);
@@ -758,14 +759,16 @@ midori_app_create_instance (MidoriApp* app)
(GIOFunc)midori_app_io_channel_watch_cb, app);
}
#endif
-
- g_free (instance_name);
- g_free (display_name);
-
#endif
return instance;
}
+const gchar*
+midori_app_get_name (MidoriApp* app)
+{
+ return app_name;
+}
+
static void
midori_app_init (MidoriApp* app)
{
@@ -793,7 +796,7 @@ midori_app_finalize (GObject* object)
{
MidoriApp* app = MIDORI_APP (object);
- katze_assign (app->name, NULL);
+ katze_assign (app_name, NULL);
katze_object_assign (app->settings, NULL);
katze_object_assign (app->bookmarks, NULL);
katze_object_assign (app->trash, NULL);
@@ -833,7 +836,7 @@ midori_app_set_property (GObject* object,
switch (prop_id)
{
case PROP_NAME:
- katze_assign (app->name, g_value_dup_string (value));
+ katze_assign (app_name, g_value_dup_string (value));
break;
case PROP_SETTINGS:
katze_object_assign (app->settings, g_value_dup_object (value));
@@ -873,7 +876,7 @@ midori_app_get_property (GObject* object,
switch (prop_id)
{
case PROP_NAME:
- g_value_set_string (value, app->name);
+ g_value_set_string (value, app_name);
break;
case PROP_SETTINGS:
g_value_set_object (value, app->settings);
diff --git a/midori/midori-app.h b/midori/midori-app.h
index 934ce0ce..c918a19e 100644
--- a/midori/midori-app.h
+++ b/midori/midori-app.h
@@ -41,6 +41,9 @@ midori_app_get_type (void) G_GNUC_CONST;
MidoriApp*
midori_app_new (void);
+const gchar*
+midori_app_get_name (MidoriApp* app);
+
gboolean
midori_app_instance_is_running (MidoriApp* app);
diff --git a/midori/midori-browser.c b/midori/midori-browser.c
index 27f4c339..e5450f7d 100644
--- a/midori/midori-browser.c
+++ b/midori/midori-browser.c
@@ -32,6 +32,10 @@
#include
#include
+#ifdef HAVE_GRANITE
+ #include
+#endif
+
#include
#ifdef HAVE_UNISTD_H
#include
@@ -247,6 +251,10 @@ static gboolean
_toggle_tabbar_smartly (MidoriBrowser* browser,
gboolean ignore_fullscreen)
{
+#ifdef HAVE_GRANITE
+ gboolean has_tabs = !(midori_browser_is_fullscreen (browser) || ignore_fullscreen);
+ /* FIXME: Toggle tabbar visibility */
+#else
gboolean has_tabs =
gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), 1) != NULL;
gboolean show_tabs =
@@ -257,6 +265,7 @@ _toggle_tabbar_smartly (MidoriBrowser* browser,
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (browser->notebook), show_tabs);
gtk_notebook_set_show_border (GTK_NOTEBOOK (browser->notebook), show_tabs);
+#endif
return has_tabs;
}
@@ -293,7 +302,8 @@ _midori_browser_update_interface (MidoriBrowser* browser)
_action_set_sensitive (browser, "Next",
midori_view_get_next_page (view) != NULL);
- _action_set_visible (browser, "AddSpeedDial", !midori_view_is_blank (view));
+ _action_set_sensitive (browser, "AddSpeedDial", !midori_view_is_blank (view));
+ _action_set_sensitive (browser, "BookmarkAdd", !midori_view_is_blank (view));
_action_set_sensitive (browser, "SaveAs", midori_view_can_save (view));
_action_set_sensitive (browser, "Print", midori_view_can_print (view));
_action_set_sensitive (browser, "ZoomIn", midori_view_can_zoom_in (view));
@@ -360,45 +370,56 @@ static void
_midori_browser_set_statusbar_text (MidoriBrowser* browser,
const gchar* text)
{
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ #if GTK_CHECK_VERSION (3, 2, 0)
+ gboolean is_location = FALSE;
+ #else
GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
gboolean is_location = widget && GTK_IS_ENTRY (widget)
&& GTK_IS_ALIGNMENT (gtk_widget_get_parent (widget));
+ #endif
katze_assign (browser->statusbar_text, midori_uri_format_for_display (text));
+ if (view == NULL)
+ return;
- if (!browser->show_statusbar && !is_location)
+ if (!gtk_widget_get_visible (browser->statusbar) && !is_location
+ && text && *text)
{
+ #if GTK_CHECK_VERSION (3, 2, 0)
+ midori_view_set_overlay_text (MIDORI_VIEW (view), browser->statusbar_text);
+ #else
GtkAction* action = _action_by_name (browser, "Location");
MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (action);
- if (text && *text)
- {
- midori_location_action_set_text (location_action, browser->statusbar_text);
- midori_location_action_set_icon (location_action, NULL);
- midori_location_action_set_secondary_icon (location_action, NULL);
- }
+ midori_location_action_set_text (location_action, browser->statusbar_text);
+ midori_location_action_set_icon (location_action, NULL);
+ midori_location_action_set_secondary_icon (location_action, NULL);
+ #endif
+ }
+ else if (!gtk_widget_get_visible (browser->statusbar) && !is_location)
+ {
+ #if GTK_CHECK_VERSION (3, 2, 0)
+ midori_view_set_overlay_text (MIDORI_VIEW (view), NULL);
+ #else
+ GtkAction* action = _action_by_name (browser, "Location");
+ MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (action);
+ if (g_object_get_data (G_OBJECT (view), "news-feeds"))
+ midori_location_action_set_secondary_icon (
+ location_action, STOCK_NEWS_FEED);
else
- {
- GtkWidget* view = midori_browser_get_current_tab (browser);
- if (G_LIKELY (view))
- {
- if (g_object_get_data (G_OBJECT (view), "news-feeds"))
- midori_location_action_set_secondary_icon (
- location_action, STOCK_NEWS_FEED);
- else
- midori_location_action_set_secondary_icon (
- location_action, GTK_STOCK_JUMP_TO);
- midori_location_action_set_text (location_action,
- midori_view_get_display_uri (MIDORI_VIEW (view)));
- midori_location_action_set_icon (location_action,
- midori_view_get_icon (MIDORI_VIEW (view)));
- }
- }
+ midori_location_action_set_secondary_icon (
+ location_action, GTK_STOCK_JUMP_TO);
+ midori_location_action_set_text (location_action,
+ midori_view_get_display_uri (MIDORI_VIEW (view)));
+ midori_location_action_set_icon (location_action,
+ midori_view_get_icon (MIDORI_VIEW (view)));
+ #endif
}
else
{
gtk_statusbar_pop (GTK_STATUSBAR (browser->statusbar), 1);
gtk_statusbar_push (GTK_STATUSBAR (browser->statusbar), 1,
- browser->statusbar_text ? browser->statusbar_text : "");
+ katze_str_non_null (browser->statusbar_text));
}
}
@@ -611,9 +632,13 @@ midori_view_notify_minimized_cb (GtkWidget* widget,
{
if (katze_object_get_boolean (widget, "minimized"))
{
+ #ifdef HAVE_GRANITE
+ /* FIXME */
+ #else
GtkNotebook* notebook = GTK_NOTEBOOK (browser->notebook);
GtkWidget* label = gtk_notebook_get_tab_label (notebook, widget);
gtk_widget_set_size_request (label, -1, -1);
+ #endif
}
else
midori_browser_notebook_size_allocate_cb (NULL, NULL, browser);
@@ -728,7 +753,8 @@ midori_browser_edit_bookmark_add_speed_dial_cb (GtkWidget* button,
midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
KatzeItem* bookmark,
gboolean new_bookmark,
- gboolean is_folder)
+ gboolean is_folder,
+ GtkWidget* proxy)
{
const gchar* title;
GtkWidget* dialog;
@@ -758,12 +784,23 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
title = new_bookmark ? _("New folder") : _("Edit folder");
else
title = new_bookmark ? _("New bookmark") : _("Edit bookmark");
- dialog = gtk_dialog_new_with_buttons (
- title, GTK_WINDOW (browser),
- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ #ifdef HAVE_GRANITE
+ if (proxy != NULL)
+ {
+ /* FIXME: granite: should return GtkWidget* like GTK+ */
+ dialog = (GtkWidget*)granite_widgets_pop_over_new ();
+ granite_widgets_pop_over_move_to_widget (
+ GRANITE_WIDGETS_POP_OVER (dialog), proxy);
+ }
+ else
+ #endif
+ {
+ dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (browser),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, NULL);
+ }
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
+ new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_window_set_icon_name (GTK_WINDOW (dialog),
new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
@@ -1319,13 +1356,13 @@ midori_view_download_save_as_response_cb (GtkWidget* dialog,
static void
midori_browser_download_status_cb (WebKitDownload* download,
GParamSpec* pspec,
- gpointer user_data)
+ GtkWidget* widget)
{
const gchar* uri = webkit_download_get_destination_uri (download);
switch (webkit_download_get_status (download))
{
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
- if (!g_app_info_launch_default_for_uri (uri, NULL, NULL))
+ if (!sokoke_show_uri (gtk_widget_get_screen (widget), uri, 0, NULL))
{
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Error opening the image!"),
@@ -1336,7 +1373,7 @@ midori_browser_download_status_cb (WebKitDownload* download,
webkit_download_cancel (download);
sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Error downloading the image!"),
- _("Can not downlaod selected image."), FALSE);
+ _("Can not download selected image."), FALSE);
break;
case WEBKIT_DOWNLOAD_STATUS_CREATED:
case WEBKIT_DOWNLOAD_STATUS_STARTED:
@@ -1380,7 +1417,7 @@ static gchar*
midori_browser_download_prepare_destination_uri (WebKitDownload* download,
const gchar* folder)
{
- const gchar* suggested_filename;
+ gchar* suggested_filename;
GFile* file_source;
gchar* file_basename;
gchar* download_dir = NULL;
@@ -1388,8 +1425,9 @@ midori_browser_download_prepare_destination_uri (WebKitDownload* download,
gchar* destination_filename;
gchar* midori_tmp_dir;
- suggested_filename = webkit_download_get_suggested_filename (download);
+ suggested_filename = sokoke_get_download_filename (download);
file_source = g_file_new_for_uri (suggested_filename);
+ g_free (suggested_filename);
file_basename = g_file_get_basename (file_source);
if (folder == NULL)
{
@@ -1426,7 +1464,7 @@ midori_view_download_requested_cb (GtkWidget* view,
midori_browser_download_prepare_destination_uri (download, NULL);
midori_browser_prepare_download (browser, download, destination_uri);
g_signal_connect (download, "notify::status",
- G_CALLBACK (midori_browser_download_status_cb), (gpointer) browser);
+ G_CALLBACK (midori_browser_download_status_cb), GTK_WIDGET (browser));
webkit_download_start (download);
g_free (destination_uri);
}
@@ -1435,6 +1473,7 @@ midori_view_download_requested_cb (GtkWidget* view,
if (g_object_get_data (G_OBJECT (download), "save-as-download"))
{
static GtkWidget* dialog = NULL;
+ gchar* filename;
if (!dialog)
{
@@ -1453,8 +1492,9 @@ midori_view_download_requested_cb (GtkWidget* view,
G_CALLBACK (midori_view_download_save_as_response_cb), browser);
}
g_object_set_data (G_OBJECT (dialog), "download", download);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog),
- webkit_download_get_suggested_filename (download));
+ filename = sokoke_get_download_filename (download);
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
+ g_free (filename);
gtk_widget_show (dialog);
}
else
@@ -1511,6 +1551,7 @@ midori_browser_tab_destroy_cb (GtkWidget* widget,
return FALSE;
}
+#ifndef HAVE_GRANITE
static void
midori_browser_notebook_resize (MidoriBrowser* browser,
GdkRectangle* allocation)
@@ -1554,33 +1595,33 @@ midori_browser_notebook_resize (MidoriBrowser* browser,
gtk_widget_set_size_request (label, new_size, -1);
}
}
+#endif
static void
midori_browser_notebook_size_allocate_cb (GtkWidget* widget,
GdkRectangle* allocation,
MidoriBrowser* browser)
{
+ #ifndef HAVE_GRANITE
if (!gtk_notebook_get_show_tabs (GTK_NOTEBOOK (browser->notebook)))
return;
midori_browser_notebook_resize (browser, allocation);
+ #endif
}
static void
_midori_browser_add_tab (MidoriBrowser* browser,
GtkWidget* view)
{
- GtkNotebook* notebook = GTK_NOTEBOOK (browser->notebook);
+ GtkWidget* notebook = browser->notebook;
+#ifndef HAVE_GRANITE
GtkWidget* tab_label;
+#endif
KatzeItem* item;
guint n;
gtk_widget_set_can_focus (view, TRUE);
- tab_label = midori_view_get_proxy_tab_label (MIDORI_VIEW (view));
- /* Don't resize empty bin, which is used for thumbnail tabs */
- if (GTK_IS_BIN (tab_label) && gtk_bin_get_child (GTK_BIN (tab_label))
- && !katze_object_get_boolean (view, "minimized"))
- gtk_widget_set_size_request (tab_label, browser->last_tab_size, -1);
item = midori_view_get_proxy_item (MIDORI_VIEW (view));
katze_array_add_item (browser->proxy_array, item);
@@ -1613,7 +1654,7 @@ _midori_browser_add_tab (MidoriBrowser* browser,
midori_view_new_window_cb, browser,
"signal::new-view",
midori_view_new_view_cb, browser,
- "signal::download-requested",
+ "signal-after::download-requested",
midori_view_download_requested_cb, browser,
"signal::search-text",
midori_view_search_text_cb, browser,
@@ -1628,17 +1669,28 @@ _midori_browser_add_tab (MidoriBrowser* browser,
if (!katze_item_get_meta_boolean (item, "append") &&
katze_object_get_boolean (browser->settings, "open-tabs-next-to-current"))
{
- n = gtk_notebook_get_current_page (notebook) + 1;
+ n = midori_browser_get_current_page (browser) + 1;
katze_array_move_item (browser->proxy_array, item, n);
}
else
n = -1;
- gtk_notebook_insert_page (notebook, view, tab_label, n);
+#ifdef HAVE_GRANITE
+ /* FIXME: Move to desired position */
+ granite_widgets_dynamic_notebook_append_page (
+ GRANITE_WIDGETS_DYNAMIC_NOTEBOOK (notebook),
+ view, midori_view_get_display_title (MIDORI_VIEW (view)), "text-plain");
+#else
+ tab_label = midori_view_get_proxy_tab_label (MIDORI_VIEW (view));
+ /* Don't resize empty bin, which is used for thumbnail tabs */
+ if (GTK_IS_BIN (tab_label) && gtk_bin_get_child (GTK_BIN (tab_label))
+ && !katze_object_get_boolean (view, "minimized"))
+ gtk_widget_set_size_request (tab_label, browser->last_tab_size, -1);
+ gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), view, tab_label, n);
+ gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (notebook), view, TRUE);
+ gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (notebook), view, TRUE);
+#endif
katze_item_set_meta_integer (item, "append", -1);
- gtk_notebook_set_tab_reorderable (notebook, view, TRUE);
- gtk_notebook_set_tab_detachable (notebook, view, TRUE);
-
/* We want the tab to be removed if the widget is destroyed */
g_signal_connect (view, "destroy",
G_CALLBACK (midori_browser_tab_destroy_cb), browser);
@@ -1731,8 +1783,8 @@ midori_browser_key_press_event (GtkWidget* widget,
&& !webkit_web_view_can_paste_clipboard (WEBKIT_WEB_VIEW (focus)))
{
/* Space at the bottom of the page: Go to next page */
+ MidoriView* view = midori_view_get_for_widget (focus);
GtkScrolledWindow* scrolled = GTK_SCROLLED_WINDOW (gtk_widget_get_parent (focus));
- MidoriView* view = MIDORI_VIEW (gtk_widget_get_parent (GTK_WIDGET (scrolled)));
GtkAdjustment* vadjust = gtk_scrolled_window_get_vadjustment (scrolled);
if (gtk_adjustment_get_value (vadjust)
== (gtk_adjustment_get_upper (vadjust) - gtk_adjustment_get_page_size (vadjust)))
@@ -2036,7 +2088,11 @@ midori_browser_class_init (MidoriBrowserClass* class)
"notebook",
"Notebook",
"The notebook containing the views",
+ #ifdef HAVE_GRANITE
+ GRANITE_WIDGETS_TYPE_DYNAMIC_NOTEBOOK,
+ #else
GTK_TYPE_NOTEBOOK,
+ #endif
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
@@ -2505,7 +2561,7 @@ _action_tab_close_activate (GtkAction* action,
{
GtkWidget* widget = midori_browser_get_current_tab (browser);
gboolean last_tab =
- gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), 1) == NULL;
+ midori_browser_get_nth_tab (browser, 1) == NULL;
if (last_tab && sokoke_is_app_or_private ())
{
gtk_widget_destroy (GTK_WIDGET (browser));
@@ -2699,14 +2755,14 @@ static void
_action_find_next_activate (GtkAction* action,
MidoriBrowser* browser)
{
- midori_findbar_find (MIDORI_FINDBAR (browser->find), TRUE);
+ midori_findbar_find_text (MIDORI_FINDBAR (browser->find), NULL, TRUE);
}
static void
_action_find_previous_activate (GtkAction* action,
MidoriBrowser* browser)
{
- midori_findbar_find (MIDORI_FINDBAR (browser->find), FALSE);
+ midori_findbar_find_text (MIDORI_FINDBAR (browser->find), NULL, FALSE);
}
static void
@@ -3026,9 +3082,9 @@ _action_window_activate_item_alt (GtkAction* action,
for (i = 0; i < n; i++)
{
GtkWidget* view;
- view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), i);
+ view = midori_browser_get_nth_tab (browser, i);
if (midori_view_get_proxy_item (MIDORI_VIEW (view)) == item)
- gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), i);
+ midori_browser_set_current_page (browser, i);
}
}
@@ -3432,8 +3488,12 @@ _action_fullscreen_activate (GtkAction* action,
gtk_widget_hide (browser->bookmarkbar);
gtk_widget_hide (browser->navigationbar);
gtk_widget_hide (browser->statusbar);
+ #ifndef HAVE_GRANITE
+ /* FIXME hide tabs */
+ #else
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (browser->notebook), FALSE);
gtk_notebook_set_show_border (GTK_NOTEBOOK (browser->notebook), FALSE);
+ #endif
gtk_window_fullscreen (GTK_WINDOW (browser));
}
@@ -3843,13 +3903,11 @@ _action_search_activate (GtkAction* action,
MidoriBrowser* browser)
{
GSList* proxies = gtk_action_get_proxies (action);
- guint i = 0;
- GtkWidget* proxy;
const gchar* uri;
gchar* search;
- while (((proxy = g_slist_nth_data (proxies, i++))))
- if (GTK_IS_TOOL_ITEM (proxy))
+ for (; proxies != NULL; proxies = g_slist_next (proxies))
+ if (GTK_IS_TOOL_ITEM (proxies->data))
{
if (!gtk_widget_get_visible (browser->navigationbar))
gtk_widget_show (browser->navigationbar);
@@ -4006,9 +4064,9 @@ midori_browser_bookmark_edit_activate_cb (GtkWidget* menuitem,
item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
if (KATZE_ITEM_IS_BOOKMARK (item))
- midori_browser_edit_bookmark_dialog_new (browser, item, FALSE, FALSE);
+ midori_browser_edit_bookmark_dialog_new (browser, item, FALSE, FALSE, NULL);
else
- midori_browser_edit_bookmark_dialog_new (browser, item, FALSE, TRUE);
+ midori_browser_edit_bookmark_dialog_new (browser, item, FALSE, TRUE, NULL);
}
static void
@@ -4106,10 +4164,19 @@ static void
_action_bookmark_add_activate (GtkAction* action,
MidoriBrowser* browser)
{
+ GtkWidget* proxy = NULL;
+ GSList* proxies = gtk_action_get_proxies (action);
+ for (; proxies != NULL; proxies = g_slist_next (proxies))
+ if (GTK_IS_TOOL_ITEM (proxies->data))
+ {
+ proxy = proxies->data;
+ break;
+ }
+
if (g_str_equal (gtk_action_get_name (action), "BookmarkFolderAdd"))
- midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, TRUE);
+ midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, TRUE, proxy);
else
- midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE);
+ midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE, proxy);
}
static void
@@ -4551,19 +4618,34 @@ _action_inspect_page_activate (GtkAction* action,
webkit_web_inspector_show (inspector);
}
+static gint
+midori_browser_get_n_pages (MidoriBrowser* browser)
+{
+ #ifdef HAVE_GRANITE
+ return granite_widgets_dynamic_notebook_get_n_pages (
+ GRANITE_WIDGETS_DYNAMIC_NOTEBOOK (browser->notebook));
+ #else
+ return gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook));
+ #endif
+}
+
static void
_action_tab_move_backward_activate (GtkAction* action,
MidoriBrowser* browser)
{
gint new_pos;
- gint cur_pos = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
- GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), cur_pos);
+ gint cur_pos = midori_browser_get_current_page (browser);
+ GtkWidget* widget = midori_browser_get_nth_tab (browser, cur_pos);
if (cur_pos > 0)
new_pos = cur_pos - 1;
else
- new_pos = gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)) - 1;
+ new_pos = midori_browser_get_n_pages (browser) - 1;
+ #ifdef HAVE_GRANITE
+ /* FIXME */
+ #else
gtk_notebook_reorder_child (GTK_NOTEBOOK (browser->notebook), widget, new_pos);
g_signal_emit (browser, signals[MOVE_TAB], 0, browser->notebook, cur_pos, new_pos);
+ #endif
}
static void
@@ -4571,22 +4653,26 @@ _action_tab_move_forward_activate (GtkAction* action,
MidoriBrowser* browser)
{
gint new_pos;
- gint cur_pos = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
- GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), cur_pos);
- if (cur_pos == (gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)) - 1))
+ gint cur_pos = midori_browser_get_current_page (browser);
+ GtkWidget* widget = midori_browser_get_nth_tab (browser, cur_pos);
+ if (cur_pos == (midori_browser_get_n_pages (browser) - 1))
new_pos = 0;
else
new_pos = cur_pos + 1;
+ #ifdef HAVE_GRANITE
+ /* FIXME */
+ #else
gtk_notebook_reorder_child (GTK_NOTEBOOK (browser->notebook), widget, new_pos);
g_signal_emit (browser, signals[MOVE_TAB], 0, browser->notebook, cur_pos, new_pos);
+ #endif
}
static void
_action_tab_previous_activate (GtkAction* action,
MidoriBrowser* browser)
{
- gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
- gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n - 1);
+ gint n = midori_browser_get_current_page (browser);
+ midori_browser_set_current_page (browser, n - 1);
}
static void
@@ -4594,10 +4680,10 @@ _action_tab_next_activate (GtkAction* action,
MidoriBrowser* browser)
{
/* Advance one tab or jump to the first one if we are at the last one */
- gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
- if (n == gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)) - 1)
+ gint n = midori_browser_get_current_page (browser);
+ if (n == midori_browser_get_n_pages (browser) - 1)
n = -1;
- gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n + 1);
+ midori_browser_set_current_page (browser, n + 1);
}
static void
@@ -4729,7 +4815,7 @@ _action_help_link_activate (GtkAction* action,
MidoriBrowser* browser)
{
const gchar* action_name;
- const gchar* uri;
+ const gchar* uri = NULL;
gint n;
#if defined (G_OS_WIN32) && defined (DOCDIR)
gchar* free_uri = NULL;
@@ -4764,9 +4850,10 @@ _action_help_link_activate (GtkAction* action,
#endif
}
else if (!strncmp ("HelpBugs", action_name, 8))
- uri = PACKAGE_BUGREPORT;
- else
- uri = NULL;
+ {
+ if (!g_spawn_command_line_async ("ubuntu-bug " PACKAGE_NAME, NULL))
+ uri = PACKAGE_BUGREPORT;
+ }
if (uri)
{
@@ -4950,6 +5037,20 @@ midori_browser_notebook_switch_page_after_cb (GtkWidget* notebook,
_midori_browser_update_progress (browser, view);
}
+#ifdef HAVE_GRANITE
+static void
+midori_browser_notebook_new_tab_created_cb (GtkWidget* notebook,
+ GraniteWidgetsTab* tab,
+ MidoriBrowser* browser)
+{
+ /* FIXME Pack view into tab: How? */
+ KatzeItem* item = katze_item_new ();
+ GtkWidget* view = midori_view_new_with_item (item, browser->settings);
+ gint n = midori_browser_add_tab (browser, view);
+ midori_browser_set_current_page (browser, n);
+}
+#endif
+
static void
midori_browser_notebook_page_reordered_cb (GtkNotebook* notebook,
MidoriView* view,
@@ -4961,6 +5062,15 @@ midori_browser_notebook_page_reordered_cb (GtkNotebook* notebook,
g_object_notify (G_OBJECT (browser), "tab");
}
+static void
+midori_browser_notebook_page_removed_cb (GtkWidget* notebook,
+ GtkWidget* view,
+ guint page_num,
+ MidoriBrowser* browser)
+{
+ _midori_browser_remove_tab (browser, view);
+}
+
static gboolean
midori_browser_notebook_reorder_tab_cb (GtkNotebook* notebook,
GtkDirectionType arg1,
@@ -5104,9 +5214,9 @@ static const GtkActionEntry entries[] =
NULL, G_CALLBACK (_action_add_speed_dial_activate) },
{ "AddDesktopShortcut", NULL,
#if HAVE_HILDON
- N_("Add Shortcut to the _desktop"), "j",
+ N_("Add Shortcut to the _desktop"), "",
#else
- N_("Create _Launcher"), "j",
+ N_("Create _Launcher"), "",
#endif
NULL, G_CALLBACK (_action_add_desktop_shortcut_activate) },
{ "AddNewsFeed", NULL,
@@ -5318,7 +5428,7 @@ static const GtkToggleActionEntry toggle_entries[] =
NULL, G_CALLBACK (_action_bookmarkbar_activate),
FALSE },
{ "Statusbar", NULL,
- N_("_Statusbar"), "",
+ N_("_Statusbar"), "j",
NULL, G_CALLBACK (_action_statusbar_activate),
FALSE },
};
@@ -5667,8 +5777,7 @@ midori_browser_accel_switch_tab_activate_cb (GtkAccelGroup* accel_group,
/* Switch to n-th tab. 9 and 0 go to the last tab. */
n = keyval - GDK_KEY_0;
browser = g_object_get_data (G_OBJECT (accel_group), "midori-browser");
- if ((view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook),
- n < 9 ? n - 1 : -1)))
+ if ((view = midori_browser_get_nth_tab (browser, n < 9 ? n - 1 : -1)))
midori_browser_set_current_tab (browser, view);
}
}
@@ -6149,7 +6258,13 @@ midori_browser_init (MidoriBrowser* browser)
vpaned = gtk_vpaned_new ();
gtk_paned_pack2 (GTK_PANED (hpaned), vpaned, TRUE, FALSE);
gtk_widget_show (vpaned);
+ #ifdef HAVE_GRANITE
+ /* FIXME: granite: should return GtkWidget* like GTK+ */
+ browser->notebook = (GtkWidget*)granite_widgets_dynamic_notebook_new ();
+ #else
browser->notebook = gtk_notebook_new ();
+ gtk_notebook_set_scrollable (GTK_NOTEBOOK (browser->notebook), TRUE);
+ #endif
#if !GTK_CHECK_VERSION (3, 0, 0)
{
/* Remove the inner border between scrollbars and the window border */
@@ -6159,7 +6274,6 @@ midori_browser_init (MidoriBrowser* browser)
g_object_unref (rcstyle);
}
#endif
- gtk_notebook_set_scrollable (GTK_NOTEBOOK (browser->notebook), TRUE);
gtk_paned_pack1 (GTK_PANED (vpaned), browser->notebook, FALSE, FALSE);
g_signal_connect (browser->notebook, "switch-page",
G_CALLBACK (midori_browser_notebook_switch_page_cb),
@@ -6167,9 +6281,17 @@ midori_browser_init (MidoriBrowser* browser)
g_signal_connect_after (browser->notebook, "switch-page",
G_CALLBACK (midori_browser_notebook_switch_page_after_cb),
browser);
+ #ifdef HAVE_GRANITE
+ g_signal_connect (browser->notebook, "new-tab-created",
+ G_CALLBACK (midori_browser_notebook_new_tab_created_cb),
+ browser);
+ #endif
g_signal_connect (browser->notebook, "page-reordered",
G_CALLBACK (midori_browser_notebook_page_reordered_cb),
browser);
+ g_signal_connect (browser->notebook, "page-removed",
+ G_CALLBACK (midori_browser_notebook_page_removed_cb),
+ browser);
g_signal_connect (browser->notebook, "size-allocate",
G_CALLBACK (midori_browser_notebook_size_allocate_cb),
browser);
@@ -6317,6 +6439,97 @@ _midori_browser_set_toolbar_style (MidoriBrowser* browser,
gtk_toolbar_style);
}
+static void
+midori_browser_toolbar_popup_context_menu_history_cb (GtkMenuItem* menu_item,
+ MidoriBrowser* browser)
+{
+ gint steps = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "steps"));
+ MidoriView* view = MIDORI_VIEW (midori_browser_get_current_tab (browser));
+ midori_view_go_back_or_forward (view, steps);
+}
+
+static void
+midori_browser_toolbar_popup_context_menu_history (MidoriBrowser* browser,
+ GtkWidget* widget,
+ gboolean back,
+ gint x,
+ gint y)
+{
+ const gint step = back ? -1 : 1;
+ gint steps = step;
+ GtkWidget* menu;
+ GtkWidget* menu_item;
+ WebKitWebBackForwardList* list;
+ WebKitWebHistoryItem* current_item;
+ WebKitWebHistoryItem* history_item;
+ WebKitWebHistoryItem* (*history_next)(WebKitWebBackForwardList*);
+ void (*history_action)(WebKitWebBackForwardList*);
+
+ list = webkit_web_view_get_back_forward_list (
+ WEBKIT_WEB_VIEW (midori_view_get_web_view (
+ MIDORI_VIEW (midori_browser_get_current_tab (browser)))));
+
+ if (!list)
+ return;
+
+ menu = gtk_menu_new ();
+
+ history_action = back ?
+ webkit_web_back_forward_list_go_back :
+ webkit_web_back_forward_list_go_forward;
+ history_next = back ?
+ webkit_web_back_forward_list_get_back_item :
+ webkit_web_back_forward_list_get_forward_item;
+ current_item = webkit_web_back_forward_list_get_current_item (list);
+
+ for (; (history_item = history_next (list)); history_action (list), steps += step)
+ {
+ #if WEBKIT_CHECK_VERSION (1, 3, 13)
+ gchar* icon_uri;
+ gchar* icon_path;
+ GdkPixbuf* pixbuf;
+ GdkPixbuf* pixbuf_scaled = NULL;
+ #endif
+
+ menu_item = gtk_image_menu_item_new_with_label (
+ webkit_web_history_item_get_title (history_item));
+ #if WEBKIT_CHECK_VERSION (1, 3, 13)
+ icon_uri = webkit_icon_database_get_icon_uri (webkit_get_icon_database (),
+ webkit_web_history_item_get_uri (history_item));
+ icon_path = katze_net_get_cached_path (NULL, icon_uri, "icons");
+ if ((pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL)))
+ {
+ gint w = 16, h = 16;
+ gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
+ GTK_ICON_SIZE_MENU, &w, &h);
+ pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf,
+ w, h, GDK_INTERP_BILINEAR);
+ }
+ gtk_image_menu_item_set_image (
+ GTK_IMAGE_MENU_ITEM (menu_item),
+ pixbuf_scaled ? gtk_image_new_from_pixbuf (pixbuf_scaled) :
+ gtk_image_new_from_stock (GTK_STOCK_FILE, GTK_ICON_SIZE_MENU));
+ g_free (icon_uri);
+ g_free (icon_path);
+ #endif
+ g_object_set_data (G_OBJECT (menu_item), "uri",
+ (gpointer) webkit_web_history_item_get_uri (history_item));
+ g_object_set_data (G_OBJECT (menu_item), "steps", GINT_TO_POINTER (steps));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+ g_signal_connect (G_OBJECT (menu_item), "activate",
+ G_CALLBACK (midori_browser_toolbar_popup_context_menu_history_cb),
+ browser);
+ if (steps == (10 - 1))
+ break;
+ }
+
+ webkit_web_back_forward_list_go_to_item (list, current_item);
+ gtk_widget_show_all (menu);
+
+ katze_widget_popup (widget, GTK_MENU (menu), NULL,
+ KATZE_MENU_POSITION_LEFT);
+}
+
static gboolean
midori_browser_toolbar_item_button_press_event_cb (GtkWidget* toolitem,
GdkEventButton* event,
@@ -6336,11 +6549,29 @@ midori_browser_toolbar_item_button_press_event_cb (GtkWidget* toolitem,
}
else if (MIDORI_EVENT_CONTEXT_MENU (event))
{
- midori_browser_toolbar_popup_context_menu_cb (
- GTK_IS_BIN (toolitem) && gtk_bin_get_child (GTK_BIN (toolitem)) ?
+ if (g_object_get_data (G_OBJECT (toolitem), "history-back"))
+ {
+ midori_browser_toolbar_popup_context_menu_history (
+ browser,
+ GTK_IS_BIN (toolitem) && gtk_bin_get_child (GTK_BIN (toolitem)) ?
gtk_widget_get_parent (toolitem) : toolitem,
- event->x, event->y, event->button, browser);
-
+ TRUE, event->x, event->y);
+ }
+ else if (g_object_get_data (G_OBJECT (toolitem), "history-forward"))
+ {
+ midori_browser_toolbar_popup_context_menu_history (
+ browser,
+ GTK_IS_BIN (toolitem) && gtk_bin_get_child (GTK_BIN (toolitem)) ?
+ gtk_widget_get_parent (toolitem) : toolitem,
+ FALSE, event->x, event->y);
+ }
+ else
+ {
+ midori_browser_toolbar_popup_context_menu_cb (
+ GTK_IS_BIN (toolitem) && gtk_bin_get_child (GTK_BIN (toolitem)) ?
+ gtk_widget_get_parent (toolitem) : toolitem,
+ event->x, event->y, event->button, browser);
+ }
return TRUE;
}
return FALSE;
@@ -6430,14 +6661,28 @@ _midori_browser_set_toolbar_items (MidoriBrowser* browser,
}
else if (token_current != token_dontcare && token_last == token_dontcare)
continue;
+ #ifdef HAVE_GRANITE
+ /* A "new tab" button is already part of the notebook */
+ else if (!strcmp (gtk_action_get_name (action), "TabNew"))
+ continue;
+ #endif
else
toolitem = gtk_action_create_tool_item (action);
if (gtk_bin_get_child (GTK_BIN (toolitem)))
+ {
+ if (!g_strcmp0 (*name, "Back"))
+ g_object_set_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (toolitem))),
+ "history-back", (void*) 0xdeadbeef);
+ else if (!g_strcmp0 (*name, "Forward"))
+ g_object_set_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (toolitem))),
+ "history-forward", (void*) 0xdeadbeef);
+
g_signal_connect (gtk_bin_get_child (GTK_BIN (toolitem)),
"button-press-event",
G_CALLBACK (midori_browser_toolbar_item_button_press_event_cb),
browser);
+ }
else
{
gtk_tool_item_set_use_drag_window (GTK_TOOL_ITEM (toolitem), TRUE);
@@ -7028,9 +7273,38 @@ midori_browser_add_tab (MidoriBrowser* browser,
g_critical ("midori_load_soup_session was not called!");
g_signal_emit (browser, signals[ADD_TAB], 0, view);
- return gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), view);
+ return midori_browser_page_num (browser, view);
}
+/**
+ * midori_browser_page_num:
+ * @browser: a #MidoriBrowser
+ * @widget: a widget in the browser
+ *
+ * Retrieves the position of @widget in the browser.
+ *
+ * If there is no page present at all, -1 is returned.
+ *
+ * Return value: the index of the widget, or -1
+ *
+ * Since: 0.4.5
+ **/
+gint
+midori_browser_page_num (MidoriBrowser* browser,
+ GtkWidget* view)
+{
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), -1);
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), -1);
+
+#ifdef HAVE_GRANITE
+ return granite_widgets_dynamic_notebook_page_num (
+ GRANITE_WIDGETS_DYNAMIC_NOTEBOOK (browser->notebook), view);
+#else
+ return gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), view);
+#endif
+}
+
+
/**
* midori_browser_remove_tab:
* @browser: a #MidoriBrowser
@@ -7275,10 +7549,15 @@ midori_browser_set_current_page (MidoriBrowser* browser,
g_return_if_fail (MIDORI_IS_BROWSER (browser));
- view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n);
+ view = midori_browser_get_nth_tab (browser, n);
g_return_if_fail (view != NULL);
+ #ifdef HAVE_GRANITE
+ granite_widgets_dynamic_notebook_set_current_page (
+ GRANITE_WIDGETS_DYNAMIC_NOTEBOOK (browser->notebook), n);
+ #else
gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
+ #endif
if (midori_view_is_blank (MIDORI_VIEW (view)))
midori_browser_activate_action (browser, "Location");
else
@@ -7305,7 +7584,12 @@ midori_browser_get_current_page (MidoriBrowser* browser)
{
g_return_val_if_fail (MIDORI_IS_BROWSER (browser), -1);
+ #ifdef HAVE_GRANITE
+ return granite_widgets_dynamic_notebook_get_current_page (
+ GRANITE_WIDGETS_DYNAMIC_NOTEBOOK (browser->notebook));
+ #else
return gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
+ #endif
}
/**
@@ -7325,9 +7609,19 @@ GtkWidget*
midori_browser_get_nth_tab (MidoriBrowser* browser,
gint page)
{
+#ifdef HAVE_GRANITE
+ GraniteWidgetsTab* tab;
+
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+ tab = granite_widgets_dynamic_notebook_get_nth_page (
+ GRANITE_WIDGETS_DYNAMIC_NOTEBOOK (browser->notebook), page);
+ return tab != NULL ? tab->widget : NULL;
+#else
g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
return gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), page);
+#endif
}
/**
@@ -7350,7 +7644,7 @@ midori_browser_set_current_tab (MidoriBrowser* browser,
g_return_if_fail (MIDORI_IS_BROWSER (browser));
g_return_if_fail (GTK_IS_WIDGET (view));
- n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), view);
+ n = midori_browser_page_num (browser, view);
midori_browser_set_current_page (browser, n);
}
@@ -7375,9 +7669,9 @@ midori_browser_get_current_tab (MidoriBrowser* browser)
g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
- n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
+ n = midori_browser_get_current_page (browser);
if (n >= 0)
- return gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n);
+ return midori_browser_get_nth_tab (browser, n);
else
return NULL;
}
diff --git a/midori/midori-browser.h b/midori/midori-browser.h
index a3cc979d..2f2cf444 100644
--- a/midori/midori-browser.h
+++ b/midori/midori-browser.h
@@ -152,6 +152,10 @@ GtkWidget*
midori_browser_get_current_tab (MidoriBrowser* browser);
#define midori_browser_get_tab midori_browser_get_current_tab
+gint
+midori_browser_page_num (MidoriBrowser* browser,
+ GtkWidget* view);
+
GList*
midori_browser_get_tabs (MidoriBrowser* browser);
diff --git a/midori/midori-extension.c b/midori/midori-extension.c
index 7927e72f..28156342 100644
--- a/midori/midori-extension.c
+++ b/midori/midori-extension.c
@@ -25,6 +25,7 @@ struct _MidoriExtensionPrivate
gchar* version;
gchar* authors;
gchar* website;
+ gchar* key;
MidoriApp* app;
gint active;
@@ -127,7 +128,8 @@ enum
PROP_DESCRIPTION,
PROP_VERSION,
PROP_AUTHORS,
- PROP_WEBSITE
+ PROP_WEBSITE,
+ PROP_KEY
};
enum {
@@ -260,6 +262,23 @@ midori_extension_class_init (MidoriExtensionClass* class)
NULL,
flags));
+ /**
+ * MidoriExtension:key:
+ *
+ * The extension key.
+ * Needed if there is more than one extension object in a single module.
+ *
+ * Since: 0.4.5
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_KEY,
+ g_param_spec_string (
+ "key",
+ "Key",
+ "The extension key",
+ NULL,
+ flags));
+
g_type_class_add_private (class, sizeof (MidoriExtensionPrivate));
}
@@ -400,6 +419,7 @@ midori_extension_finalize (GObject* object)
katze_assign (extension->priv->version, NULL);
katze_assign (extension->priv->authors, NULL);
katze_assign (extension->priv->website, NULL);
+ katze_assign (extension->priv->key, NULL);
katze_assign (extension->priv->config_dir, NULL);
g_list_free (extension->priv->lsettings);
@@ -446,6 +466,9 @@ midori_extension_set_property (GObject* object,
case PROP_WEBSITE:
katze_assign (extension->priv->website, g_value_dup_string (value));
break;
+ case PROP_KEY:
+ katze_assign (extension->priv->key, g_value_dup_string (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -477,6 +500,9 @@ midori_extension_get_property (GObject* object,
case PROP_WEBSITE:
g_value_set_string (value, extension->priv->website);
break;
+ case PROP_KEY:
+ g_value_set_string (value, extension->priv->key);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/midori/midori-locationaction.c b/midori/midori-locationaction.c
index 6f218e07..d7f97b24 100644
--- a/midori/midori-locationaction.c
+++ b/midori/midori-locationaction.c
@@ -369,6 +369,77 @@ midori_location_action_popup_position (MidoriLocationAction* action,
gtk_window_move (GTK_WINDOW (popup), wx, wy);
}
+static int
+midori_location_action_add_search_engines (MidoriLocationAction* action,
+ GtkListStore* store,
+ gint matches)
+{
+ KatzeItem* item;
+ gint i = 0;
+ GtkStyle* style;
+
+ gtk_widget_realize (action->treeview);
+ style = gtk_widget_get_style (action->treeview);
+
+ /* FIXME: choose 3 most frequently except for default */
+ KATZE_ARRAY_FOREACH_ITEM (item, action->search_engines)
+ {
+ gchar* uri;
+ gchar* title;
+ const gchar* text;
+ gchar* desc;
+ GdkPixbuf* icon;
+
+ uri = midori_uri_for_search (katze_item_get_uri (item), action->key);
+ title = g_strdup_printf (_("Search with %s"), katze_item_get_name (item));
+ text = katze_item_get_text (item);
+ desc = g_strdup_printf ("%s\n%s", title, text ? text : uri);
+ icon = midori_search_action_get_icon (item, action->treeview, NULL, FALSE);
+ gtk_list_store_insert_with_values (store, NULL, matches + i,
+ URI_COL, uri, TITLE_COL, desc, YALIGN_COL, 0.25,
+ BACKGROUND_COL, style ? &style->bg[GTK_STATE_NORMAL] : NULL,
+ STYLE_COL, 1, FAVICON_COL, icon, -1);
+ g_free (uri);
+ g_free (title);
+ g_free (desc);
+ if (icon != NULL)
+ g_object_unref (icon);
+ i++;
+
+ if (i > 2 && matches > 0)
+ {
+ gtk_list_store_insert_with_values (store, NULL, matches + i,
+ URI_COL, "about:search", TITLE_COL, _("Search with..."),
+ YALIGN_COL, 0.25,
+ BACKGROUND_COL, style ? &style->bg[GTK_STATE_NORMAL] : NULL,
+ STYLE_COL, 1, FAVICON_COL, NULL, -1);
+ i++;
+ break;
+ }
+ }
+ return i;
+}
+
+static void
+midori_location_action_complete (MidoriLocationAction* action,
+ gboolean new_tab,
+ const gchar* uri)
+{
+ if (!strcmp (uri, "about:search"))
+ {
+ GtkListStore* store = GTK_LIST_STORE (action->completion_model);
+ gtk_list_store_clear (store);
+ midori_location_action_popup_position (action,
+ midori_location_action_add_search_engines (action, store, 0));
+ }
+ else
+ {
+ midori_location_action_popdown_completion (action);
+ gtk_entry_set_text (GTK_ENTRY (action->entry), uri);
+ g_signal_emit (action, signals[SUBMIT_URI], 0, uri, new_tab);
+ }
+}
+
static gboolean
midori_location_action_treeview_button_press_cb (GtkWidget* treeview,
GdkEventButton* event,
@@ -384,13 +455,9 @@ midori_location_action_treeview_button_press_cb (GtkWidget* treeview,
gtk_tree_model_get_iter (action->completion_model, &iter, path);
gtk_tree_path_free (path);
-
- midori_location_action_popdown_completion (action);
-
gtk_tree_model_get (action->completion_model, &iter, URI_COL, &uri, -1);
- gtk_entry_set_text (GTK_ENTRY (action->entry), uri);
- g_signal_emit (action, signals[SUBMIT_URI], 0, uri,
- MIDORI_MOD_NEW_TAB (event->state));
+ midori_location_action_complete (action,
+ MIDORI_MOD_NEW_TAB (event->state), uri);
g_free (uri);
return TRUE;
@@ -411,7 +478,6 @@ midori_location_action_popup_timeout_cb (gpointer data)
static sqlite3_stmt* stmt;
const gchar* sqlcmd;
gint matches, searches;
- GtkStyle* style;
if (!action->entry || !gtk_widget_has_focus (action->entry) || !action->history)
return FALSE;
@@ -519,6 +585,8 @@ midori_location_action_popup_timeout_cb (gpointer data)
renderer = gtk_cell_renderer_text_new ();
g_object_set_data (G_OBJECT (renderer), "location-action", action);
gtk_cell_renderer_set_fixed_size (renderer, 1, -1);
+ gtk_cell_renderer_text_set_fixed_height_from_font (
+ GTK_CELL_RENDERER_TEXT (renderer), 2);
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer,
"cell-background-gdk", BACKGROUND_COL,
@@ -537,8 +605,6 @@ midori_location_action_popup_timeout_cb (gpointer data)
gtk_list_store_clear (store);
matches = searches = 0;
- gtk_widget_realize (action->treeview);
- style = gtk_widget_get_style (action->treeview);
while (result == SQLITE_ROW)
{
sqlite3_int64 type = sqlite3_column_int64 (stmt, 0);
@@ -577,35 +643,7 @@ midori_location_action_popup_timeout_cb (gpointer data)
}
if (action->search_engines)
- {
- KatzeItem* item;
- i = 0;
- KATZE_ARRAY_FOREACH_ITEM (item, action->search_engines)
- {
- gchar* uri;
- gchar* title;
- const gchar* text;
- gchar* desc;
- GdkPixbuf* icon;
-
- uri = midori_uri_for_search (katze_item_get_uri (item), action->key);
- title = g_strdup_printf (_("Search with %s"), katze_item_get_name (item));
- text = katze_item_get_text (item);
- desc = g_strdup_printf ("%s\n%s", title, text ? text : uri);
- icon = midori_search_action_get_icon (item, action->treeview, NULL, FALSE);
- gtk_list_store_insert_with_values (store, NULL, matches + i,
- URI_COL, uri, TITLE_COL, desc, YALIGN_COL, 0.25,
- BACKGROUND_COL, style ? &style->bg[GTK_STATE_NORMAL] : NULL,
- STYLE_COL, 1, FAVICON_COL, icon, -1);
- g_free (uri);
- g_free (title);
- g_free (desc);
- if (icon != NULL)
- g_object_unref (icon);
- i++;
- }
- searches += i;
- }
+ searches += midori_location_action_add_search_engines (action, store, matches);
if (!gtk_widget_get_visible (action->popup))
{
@@ -918,27 +956,30 @@ midori_location_action_key_press_event_cb (GtkEntry* entry,
GtkTreeModel* model = location_action->completion_model;
GtkTreeIter iter;
gint selected = location_action->completion_index;
- midori_location_action_popdown_completion (location_action);
if (selected > -1 &&
gtk_tree_model_iter_nth_child (model, &iter, NULL, selected))
{
gchar* uri;
gtk_tree_model_get (model, &iter, URI_COL, &uri, -1);
- gtk_entry_set_text (entry, uri);
if (is_enter)
- g_signal_emit (action, signals[SUBMIT_URI], 0, uri,
- MIDORI_MOD_NEW_TAB (event->state));
+ midori_location_action_complete (location_action,
+ MIDORI_MOD_NEW_TAB (event->state), uri);
+ else
+ {
+ midori_location_action_popdown_completion (location_action);
+ gtk_entry_set_text (entry, uri);
+ }
g_free (uri);
return TRUE;
}
+ midori_location_action_popdown_completion (location_action);
}
- if (is_enter)
- if ((text = gtk_entry_get_text (entry)) && *text)
- g_signal_emit (action, signals[SUBMIT_URI], 0, text,
- MIDORI_MOD_NEW_TAB (event->state));
+ if (is_enter && (text = gtk_entry_get_text (entry)) && *text)
+ g_signal_emit (action, signals[SUBMIT_URI], 0, text,
+ MIDORI_MOD_NEW_TAB (event->state));
break;
case GDK_KEY_Escape:
{
diff --git a/midori/midori-preferences.c b/midori/midori-preferences.c
index 3ec6bdff..be60c466 100644
--- a/midori/midori-preferences.c
+++ b/midori/midori-preferences.c
@@ -429,11 +429,13 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
button = katze_property_proxy (settings, "open-new-pages-in", NULL);
SPANNED_ADD (button);
#if !HAVE_HILDON
- button = katze_property_proxy (settings, "always-show-tabbar", NULL);
- INDENTED_ADD (button);
button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
+ INDENTED_ADD (button);
+ #ifndef HAVE_GRANITE
+ button = katze_property_proxy (settings, "always-show-tabbar", NULL);
SPANNED_ADD (button);
#endif
+ #endif
button = katze_property_proxy (settings, "open-tabs-next-to-current", NULL);
INDENTED_ADD (button);
button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
diff --git a/midori/midori-view.c b/midori/midori-view.c
index cc7ee000..bb22a2f3 100644
--- a/midori/midori-view.c
+++ b/midori/midori-view.c
@@ -13,11 +13,17 @@
#include "midori-view.h"
#include "midori-browser.h"
#include "midori-searchaction.h"
+#include "midori-app.h"
#include "midori-platform.h"
#include "midori-core.h"
+#include "midori-findbar.h"
#include "marshal.h"
+#ifdef HAVE_GRANITE
+#include
+#endif
+
#include
#include
#include
@@ -108,6 +114,12 @@ struct _MidoriView
gboolean back_forward_set;
GHashTable* memory;
GtkWidget* scrolled_window;
+
+ #if GTK_CHECK_VERSION (3, 2, 0)
+ GtkWidget* overlay;
+ GtkWidget* overlay_label;
+ GtkWidget* overlay_find;
+ #endif
};
struct _MidoriViewClass
@@ -595,10 +607,29 @@ midori_view_class_init (MidoriViewClass* class)
flags));
}
+#ifdef HAVE_GRANITE
+static GraniteWidgetsTab*
+midori_view_get_tab (MidoriView* view)
+{
+ GraniteWidgetsDynamicNotebook* notebook;
+ GraniteWidgetsTab* tab = NULL;
+
+ notebook = (GraniteWidgetsDynamicNotebook*)gtk_widget_get_parent ((GtkWidget*)view);
+ if (notebook != NULL)
+ tab = granite_widgets_dynamic_notebook_get_nth_page (notebook,
+ granite_widgets_dynamic_notebook_page_num (notebook, (GtkWidget*)view));
+
+ return tab;
+}
+#endif
+
static void
midori_view_set_title (MidoriView* view, const gchar* title)
{
const gchar* display_title;
+ #ifdef HAVE_GRANITE
+ GraniteWidgetsTab* tab;
+ #endif
if (!title)
title = view->uri;
@@ -632,6 +663,12 @@ midori_view_set_title (MidoriView* view, const gchar* title)
#endif
display_title = midori_view_get_display_title (view);
+ #ifdef HAVE_GRANITE
+ /* FIXME: granite: GraniteWidgetsTab.text should be a property */
+ tab = midori_view_get_tab (view);
+ if (tab != NULL)
+ katze_assign (tab->text, g_strdup (display_title));
+ #endif
if (view->tab_label)
{
/* If the title starts with the presumed name of the website, we
@@ -667,6 +704,11 @@ midori_view_apply_icon (MidoriView* view,
GdkPixbuf* icon,
const gchar* icon_name)
{
+ #ifdef HAVE_GRANITE
+ GraniteWidgetsTab* tab = midori_view_get_tab (view);
+ g_object_set (tab, "pixbuf", icon, NULL);
+ #endif
+
katze_item_set_icon (view->item, icon_name);
/* katze_item_get_image knows about this pixbuf */
g_object_set_data_full (G_OBJECT (view->item), "pixbuf", g_object_ref (icon),
@@ -898,6 +940,10 @@ midori_view_update_load_status (MidoriView* view,
view->load_status = load_status;
g_object_notify (G_OBJECT (view), "load-status");
+ #ifdef HAVE_GRANITE
+ g_object_set (midori_view_get_tab (view),
+ "loading", view->load_status != MIDORI_LOAD_FINISHED, NULL);
+ #endif
if (view->tab_icon)
katze_throbber_set_animated (KATZE_THROBBER (view->tab_icon),
view->load_status != MIDORI_LOAD_FINISHED);
@@ -1476,18 +1522,21 @@ webkit_web_view_load_finished_cb (WebKitWebView* web_view,
{
JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
- /* Icon: URI, News Feed: $URI|title */
+ /* Icon: URI, News Feed: $URI|title, Search: :URI|title */
gchar* value = sokoke_js_script_eval (js_context,
- "(function (l) { var f = new Array (); for (i in l) "
+ "(function (l) { var f = new Array (); for (var i in l) "
"{ var t = l[i].type; var r = l[i].rel; "
"if (t && (t.indexOf ('rss') != -1 || t.indexOf ('atom') != -1)) "
"f.push ('$' + l[i].href + '|' + l[i].title);"
+ "else if (r == 'search' && t == 'application/opensearchdescription+xml') "
+ "f.push (':' + l[i].href + '|' + l[i].title); "
#if !WEBKIT_CHECK_VERSION (1, 1, 18)
"else if (r && r.indexOf ('icon') != -1) f.push (l[i].href); "
#endif
"} return f; })("
"document.getElementsByTagName ('link'));", NULL);
+ /* FIXME: If URI or title contains , parsing will break */
gchar** items = g_strsplit (value, ",", 0);
gchar** current_item = items;
gchar* default_uri = NULL;
@@ -1511,7 +1560,7 @@ webkit_web_view_load_finished_cb (WebKitWebView* web_view,
continue;
title = strchr (uri_and_title, '|');
if (title == NULL)
- continue;
+ goto news_feeds_continue;
title++;
uri = g_strndup (uri_and_title, title - 1 - uri_and_title);
@@ -1524,11 +1573,28 @@ webkit_web_view_load_finished_cb (WebKitWebView* web_view,
else
g_free (uri);
}
+ else if (uri_and_title[0] == ':')
+ {
+ const gchar* title;
+
+ uri_and_title++;
+ if (uri_and_title == NULL)
+ continue;
+ title = strchr (uri_and_title, '|');
+ if (title == NULL)
+ goto news_feeds_continue;
+ title++;
+ /* TODO: Parse search engine XML
+ midori_view_add_info_bar (view, GTK_MESSAGE_INFO, title,
+ G_CALLBACK (midori_view_open_search_response_cb), view,
+ _("_Save Search engine"), GTK_RESPONSE_ACCEPT, NULL); */
+ }
#if !WEBKIT_CHECK_VERSION (1, 1, 18)
else
katze_assign (view->icon_uri, g_strdup (uri_and_title));
#endif
+ news_feeds_continue:
current_item++;
}
g_strfreev (items);
@@ -1716,12 +1782,7 @@ midori_view_web_view_button_press_event_cb (WebKitWebView* web_view,
view->button_press_handled = TRUE;
return TRUE;
}
- else if (MIDORI_MOD_SCROLL (event->state))
- {
- midori_view_set_zoom_level (MIDORI_VIEW (view), 1.0);
- return FALSE; /* Allow Ctrl + Middle click */
- }
- else if (view->middle_click_opens_selection)
+ if (view->middle_click_opens_selection)
{
gboolean is_editable;
WebKitHitTestResult* result;
@@ -1731,56 +1792,63 @@ midori_view_web_view_button_press_event_cb (WebKitWebView* web_view,
context = katze_object_get_int (result, "context");
is_editable = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
g_object_unref (result);
- if (is_editable)
- return FALSE;
-
- clipboard = gtk_clipboard_get_for_display (
- gtk_widget_get_display (GTK_WIDGET (view)),
- GDK_SELECTION_PRIMARY);
- if ((uri = gtk_clipboard_wait_for_text (clipboard)))
+ if (!is_editable)
{
- guint i = 0;
- while (uri[i++] != '\0')
- if (uri[i] == '\n' || uri[i] == '\r')
- uri[i] = ' ';
- g_strstrip (uri);
-
- /* Hold Alt to search for the selected word */
- if (event->state & GDK_MOD1_MASK)
+ clipboard = gtk_clipboard_get_for_display (
+ gtk_widget_get_display (GTK_WIDGET (view)),
+ GDK_SELECTION_PRIMARY);
+ if ((uri = gtk_clipboard_wait_for_text (clipboard)))
{
- new_uri = sokoke_magic_uri (uri);
- if (!new_uri)
+ guint i = 0;
+ while (uri[i++] != '\0')
+ if (uri[i] == '\n' || uri[i] == '\r')
+ uri[i] = ' ';
+ g_strstrip (uri);
+
+ /* Hold Alt to search for the selected word */
+ if (event->state & GDK_MOD1_MASK)
{
- gchar* search = katze_object_get_string (
- view->settings, "location-entry-search");
- new_uri = midori_uri_for_search (search, uri);
- g_free (search);
+ new_uri = sokoke_magic_uri (uri);
+ if (!new_uri)
+ {
+ gchar* search = katze_object_get_string (
+ view->settings, "location-entry-search");
+ new_uri = midori_uri_for_search (search, uri);
+ g_free (search);
+ }
+ katze_assign (uri, new_uri);
+ }
+ else if (midori_uri_is_location (uri))
+ {
+ if (MIDORI_MOD_NEW_TAB (event->state))
+ {
+ background = view->open_tabs_in_the_background;
+ if (MIDORI_MOD_BACKGROUND (event->state))
+ background = !background;
+ g_signal_emit (view, signals[NEW_TAB], 0, uri, background);
+ }
+ else
+ {
+ midori_view_set_uri (MIDORI_VIEW (view), uri);
+ gtk_widget_grab_focus (GTK_WIDGET (view));
+ }
+ g_free (uri);
+ view->button_press_handled = TRUE;
+ return TRUE;
+ }
+ else
+ {
+ g_free (uri);
}
- katze_assign (uri, new_uri);
}
- else if (!midori_uri_is_location (uri))
- {
- g_free (uri);
- return FALSE;
- }
-
- if (MIDORI_MOD_NEW_TAB (event->state))
- {
- background = view->open_tabs_in_the_background;
- if (MIDORI_MOD_BACKGROUND (event->state))
- background = !background;
- g_signal_emit (view, signals[NEW_TAB], 0, uri, background);
- }
- else
- {
- midori_view_set_uri (MIDORI_VIEW (view), uri);
- gtk_widget_grab_focus (GTK_WIDGET (view));
- }
- g_free (uri);
- view->button_press_handled = TRUE;
- return TRUE;
}
}
+ if (MIDORI_MOD_SCROLL (event->state))
+ {
+ midori_view_set_zoom_level (MIDORI_VIEW (view), 1.0);
+ return FALSE; /* Allow Ctrl + Middle click */
+ }
+ return FALSE;
break;
case 3:
if (event->state & GDK_CONTROL_MASK)
@@ -1892,7 +1960,7 @@ gtk_widget_key_press_event_cb (WebKitWebView* web_view,
" border:1px solid gray; padding:0 0.1em 0.2em 0.1em !important;"
" position:absolute; display:inline !important; }');"
" var label_count = 0;"
- " for (i in document.links) {"
+ " for (var i in document.links) {"
" if (document.links[i].href && document.links[i].insertBefore) {"
" var child = document.createElement ('span');"
" if (document.links[i].accessKey && isNaN (document.links[i].accessKey)) {"
@@ -1981,7 +2049,12 @@ gtk_widget_key_press_event_cb (WebKitWebView* web_view,
&& !webkit_web_view_can_paste_clipboard (web_view))
{
gchar* text = character ? g_strdup_printf ("%c", character) : NULL;
+ #if GTK_CHECK_VERSION(3, 2, 0)
+ midori_findbar_search_text (MIDORI_FINDBAR (view->overlay_find),
+ (GtkWidget*)view, TRUE, katze_str_non_null (text));
+ #else
g_signal_emit (view, signals[SEARCH_TEXT], 0, TRUE, text ? text : "");
+ #endif
g_free (text);
return TRUE;
}
@@ -2286,7 +2359,8 @@ midori_view_populate_popup (MidoriView* view,
context = katze_object_get_int (view->hit_test, "context");
has_selection = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;
/* Ensure view->selected_text */
- midori_view_has_selection (view);
+ if (!midori_view_has_selection (view))
+ has_selection = false;
is_editable = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
is_image = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;
is_media = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA;
@@ -2505,6 +2579,7 @@ midori_view_populate_popup (MidoriView* view,
midori_view_insert_menu_item (menu_shell, 0,
_("_Search the Web"), GTK_STOCK_FIND,
G_CALLBACK (midori_web_view_menu_search_web_activate_cb), widget);
+ /* FIXME: choose 3 most frequently */
g_strstrip (view->selected_text);
if (midori_uri_is_valid (view->selected_text))
@@ -2718,8 +2793,8 @@ static gboolean
webkit_web_view_web_view_ready_cb (GtkWidget* web_view,
MidoriView* view)
{
- GtkWidget* new_view = gtk_widget_get_parent (gtk_widget_get_parent (web_view));
MidoriNewView where = MIDORI_NEW_VIEW_TAB;
+ GtkWidget* new_view = GTK_WIDGET (midori_view_get_for_widget (web_view));
/* FIXME: Open windows opened by scripts in tabs if they otherwise
would be replacing the page the user opened. */
@@ -2770,6 +2845,7 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
gchar* content_type;
gchar* description;
gchar* file_type;
+ gchar* name;
gchar* file_name;
WebKitDownload *download;
WebKitWebDataSource* datasource;
@@ -2786,9 +2862,6 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
GtkIconTheme* icon_theme;
gint response;
- if (web_frame != webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view)))
- return FALSE;
-
if (webkit_web_view_can_show_mime_type (WEBKIT_WEB_VIEW (web_view), mime_type))
{
gboolean view_source = FALSE;
@@ -2836,8 +2909,9 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
g_free (description);
download = webkit_download_new (request);
- file_name = g_strdup_printf (_("File Name: %s"),
- webkit_download_get_suggested_filename (download));
+ name = sokoke_get_download_filename (download);
+ file_name = g_strdup_printf (_("File Name: %s"), name);
+ g_free (name);
g_object_unref (download);
/* Link Fingerprint */
@@ -2879,26 +2953,27 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
g_object_set_data (G_OBJECT (view), "open-download", (gpointer)0);
switch (response)
{
- case 4:
+ case 4:
g_object_set_data (G_OBJECT (view), "save-as-download", (gpointer)1);
webkit_web_policy_decision_download (decision);
- webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (view->web_view));
- return TRUE;
+ break;
case 3:
g_object_set_data (G_OBJECT (view), "open-download", (gpointer)1);
case 1:
webkit_web_policy_decision_download (decision);
- /* Apparently WebKit will continue loading which ends in an error.
- It's unclear whether it's a bug or we are doing something wrong. */
- webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (view->web_view));
- return TRUE;
+ break;
case 2:
+ case GTK_RESPONSE_DELETE_EVENT:
+ webkit_web_policy_decision_ignore (decision);
+ break;
default:
- /* Apparently WebKit will continue loading which ends in an error.
- It's unclear whether it's a bug or we are doing something wrong. */
- webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (view->web_view));
- return FALSE;
+ g_warn_if_reached ();
}
+
+ /* Apparently WebKit will continue loading which ends in an error.
+ It's unclear whether it's a bug or we are doing something wrong. */
+ webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (view->web_view));
+ return TRUE;
}
static gboolean
@@ -3106,7 +3181,27 @@ midori_view_init (MidoriView* view)
view->scrolled_window = katze_scrolled_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view->scrolled_window),
GTK_SHADOW_NONE);
+
+ #if GTK_CHECK_VERSION(3, 2, 0)
+ view->overlay = gtk_overlay_new ();
+ gtk_widget_show (view->overlay);
+ gtk_container_add (GTK_CONTAINER (view->overlay), view->scrolled_window);
+ gtk_box_pack_start (GTK_BOX (view), view->overlay, TRUE, TRUE, 0);
+
+ /* Overlays must be created before showing GtkOverlay as of GTK+ 3.2 */
+ view->overlay_label = gtk_label_new (NULL);
+ gtk_widget_set_halign (view->overlay_label, GTK_ALIGN_START);
+ gtk_widget_set_valign (view->overlay_label, GTK_ALIGN_END);
+ gtk_overlay_add_overlay (GTK_OVERLAY (view->overlay), view->overlay_label);
+ view->overlay_find = g_object_new (MIDORI_TYPE_FINDBAR, NULL);
+ gtk_widget_set_halign (view->overlay_find, GTK_ALIGN_END);
+ gtk_widget_set_valign (view->overlay_find, GTK_ALIGN_START);
+ gtk_overlay_add_overlay (GTK_OVERLAY (view->overlay),
+ view->overlay_find);
+ gtk_widget_set_no_show_all (view->overlay_find, TRUE);
+ #else
gtk_box_pack_start (GTK_BOX (view), view->scrolled_window, TRUE, TRUE, 0);
+ #endif
g_signal_connect (view->item, "meta-data-changed",
G_CALLBACK (midori_view_item_meta_data_changed), view);
@@ -3696,22 +3791,22 @@ midori_view_construct_web_view (MidoriView* view)
NULL);
}
-static gchar* list_netscape_plugins ()
+static void
+list_netscape_plugins (GString* ns_plugins,
+ JSContextRef js_context)
{
- if (midori_web_settings_has_plugin_support ())
- {
- GtkWidget* web_view = webkit_web_view_new ();
- WebKitWebFrame* web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
- JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
+ if (!midori_web_settings_has_plugin_support ())
+ return;
+
/* Joins available plugins like this: URI1|title1,URI2|title2 */
gchar* value = sokoke_js_script_eval (js_context,
- "function plugins (l) { var f = new Array (); for (i in l) "
+ "function plugins (l) { var f = new Array (); for (var i in l) "
"{ var p = l[i].name + '|' + l[i].filename; "
"if (f.indexOf (p) == -1) f.push (p); } return f; }"
"plugins (navigator.plugins)", NULL);
gchar** items = g_strsplit (value, ",", 0);
guint i = 0;
- GString* ns_plugins = g_string_new ("Netscape Plugins: ");
+ g_string_append (ns_plugins, "Netscape Plugins: ");
if (items != NULL)
while (items[i] != NULL)
{
@@ -3732,19 +3827,48 @@ static gchar* list_netscape_plugins ()
g_string_append (ns_plugins, "
");
g_strfreev (items);
g_free (value);
- gtk_widget_destroy (web_view);
- return g_string_free (ns_plugins, FALSE);
- }
- else
- return g_strdup ("");
+}
+
+static void
+list_geolocation (GString* markup)
+{
+ g_string_append (markup,
+ " "
+ "No Geolocation without Javascript "
+ "");
}
static gchar*
-list_video_formats ()
+list_video_formats (JSContextRef js_context)
{
- GtkWidget* web_view = webkit_web_view_new ();
- WebKitWebFrame* web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
- JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
gchar* value = sokoke_js_script_eval (js_context,
"var supported = function (format) { "
"var video = document.createElement('video');"
@@ -3757,10 +3881,27 @@ list_video_formats ()
"' WebM [' + "
"supported('video/webm; codecs=\"vp8, vorbis\"') + ']' "
"", NULL);
- gtk_widget_destroy (web_view);
return value;
}
+static const gchar* valid_about_uris[] = {
+ "about:widgets",
+ "about:private",
+ "error:nodocs",
+ "http://.invalid",
+ "about:geolocation",
+};
+
+static void
+list_about_uris (GString* markup)
+{
+ g_string_append (markup, "");
+ guint i;
+ for (i = 0; i < G_N_ELEMENTS (valid_about_uris); i++)
+ g_string_append_printf (markup, "%s ",
+ valid_about_uris[i], valid_about_uris[i]);
+}
+
static gchar*
prepare_speed_dial_html (MidoriView* view,
gboolean load_missing)
@@ -4033,6 +4174,13 @@ midori_view_set_uri (MidoriView* view,
_("The language and timezone are not revealed to websites."),
_("Flash and other Netscape plugins cannot be listed by websites."));
}
+ else if (!strcmp (uri, "about:geolocation"))
+ {
+ GString* markup = g_string_new ("");
+ katze_assign (view->uri, g_strdup (uri));
+ list_geolocation (markup);
+ data = g_string_free (markup, FALSE);
+ }
else if (!strcmp (uri, "about:") || !strcmp (uri, "about:version"))
{
gchar* arguments = g_strjoinv (" ", sokoke_get_argv (NULL));
@@ -4042,8 +4190,12 @@ midori_view_set_uri (MidoriView* view,
const gchar* sys_name = midori_web_settings_get_system_name (
&architecture, &platform);
gchar* ident = katze_object_get_string (view->settings, "user-agent");
- gchar* netscape_plugins = list_netscape_plugins ();
- gchar* video_formats = list_video_formats ();
+ WebKitWebFrame* web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (view->web_view));
+ JSContextRef js_context = webkit_web_frame_get_global_context (web_frame);
+ gchar* video_formats = list_video_formats (js_context);
+ GString* more = g_string_new ("");
+ list_netscape_plugins (more, js_context);
+ list_about_uris (more);
katze_assign (view->uri, g_strdup (uri));
data = g_strdup_printf (
@@ -4054,12 +4206,13 @@ midori_view_set_uri (MidoriView* view,
"style=\"position: absolute; right: 15px; bottom: 15px; z-index: -9;\">"
"
"
"Command line %s "
- "Midori %s "
+ "Midori %s (%s) "
"WebKitGTK+ %d.%d.%d (%d.%d.%d) "
"GTK+ %d.%d.%d (%d.%d.%d) "
"Glib %d.%d.%d (%d.%d.%d) "
"libsoup %s "
"cairo %s (%s) "
+ "granite %s "
"libnotify %s "
"single instance %s "
"Platform %s %s %s "
@@ -4070,7 +4223,7 @@ midori_view_set_uri (MidoriView* view,
"