Merge branch 'upstream-unstable'

This commit is contained in:
Yves-Alexis Perez 2012-04-14 23:53:10 +02:00
commit a489245d13
69 changed files with 15608 additions and 13291 deletions

2
.gitignore vendored
View file

@ -2,7 +2,7 @@ Makefile
.waf-* .waf-*
.lock-wscript .lock-wscript
_build_ _build
po/.intltool-merge-cache po/.intltool-merge-cache
po/LINGUAS po/LINGUAS

View file

@ -1,5 +1,31 @@
This file is licensed under the terms of the expat license, see the file EXPAT. This file is licensed under the terms of the expat license, see the file EXPAT.
v0.4.5:
+ Work around black border around widgets on Win32
+ Whitelist direct/ re-directed navigation requests in adblock
+ Require Vala 0.14
+ Provide geolocation diagnostics in about:geolocation
+ List available about: URLs and app instance name in about:version
+ Replace illegal characters in download filenames
+ Tweak app options on Win32 and use ShellExecuteEx in sokoke_show_uri
+ Use sokoke_show_uri in midori_browser_download_status_cb
+ External Download manager Steadyflow and Aria2 (with cookies)
+ Ensure adblock config folder when blocking images
+ Use sqlite WAL mode for history if available
+ Allow relative -c/ --config path
+ Context menus on Back and Forward toolbar items
+ Always show the tabbar by default
+ Use ubuntu-bug if it exists
+ Show inline find while typing and statusbar text in overlay with GTK+ 3.2
+ Esc/ closing "downloads still active" should cancel, not continue
+ Optional Granite support for notebook and bookmark dialog as pop-over
+ Ctrl+j to toggle statusbar aka downloads
+ Show at most 3 search engines in completion
+ Don't replace existing onclick/ blur with autosuggest
+ Implement low_memory_profile for FreeBSD and Win32
+ Use var in internal javascript, to fix Google apps
+ Handle download requests in frames
v0.4.4: v0.4.4:
+ Disable page cache with < 352 MB RAM + Disable page cache with < 352 MB RAM
+ Display filename in download dialog + Display filename in download dialog

14
INSTALL
View file

@ -37,7 +37,7 @@ Midori is now built with debugging symbols.
Make sure you have installed 'gdb', the GNU Debugger. Make sure you have installed 'gdb', the GNU Debugger.
Run Midori as 'gdb _build_/default/midori/midori'. Run Midori as 'gdb _build/default/midori/midori'.
Inside gdb, type 'run'. Inside gdb, type 'run'.
@ -49,29 +49,29 @@ function names and line numbers.
If the problem is a warning and not a crash, try this: If the problem is a warning and not a crash, try this:
'G_DEBUG=all gdb _build_/default/midori/midori' 'G_DEBUG=all gdb _build/default/midori/midori'
If you are interested in HTTP communication, try this: If you are interested in HTTP communication, try this:
'MIDORI_SOUP_DEBUG=2 _build_/default/midori/midori' 'MIDORI_SOUP_DEBUG=2 _build/default/midori/midori'
Where '2' can be a level between 0 and 3. Where '2' can be a level between 0 and 3.
If you are interested in (non-) touchscreen behaviour, try this: If you are interested in (non-) touchscreen behaviour, try this:
'MIDORI_TOUCHSCREEN=1 _build_/default/midori/midori', or 'MIDORI_TOUCHSCREEN=1 _build/default/midori/midori', or
'MIDORI_TOUCHSCREEN=0 _build_/default/midori/midori' 'MIDORI_TOUCHSCREEN=0 _build/default/midori/midori'
If you want to "dry run" without WebKitGTK+ rendering, try this: If you want to "dry run" without WebKitGTK+ rendering, try this:
'MIDORI_UNARMED=1 _build_/default/midori/midori' 'MIDORI_UNARMED=1 _build/default/midori/midori'
To disable Netscape plugins, use MOZ_PLUGIN_PATH=/. To disable Netscape plugins, use MOZ_PLUGIN_PATH=/.
To debug extensions you can specify the path: To debug extensions you can specify the path:
'export MIDORI_EXTENSION_PATH=_build_/default/extensions' 'export MIDORI_EXTENSION_PATH=_build/default/extensions'
For further information a tutorial for gdb and For further information a tutorial for gdb and
reading up on how you can install debugging reading up on how you can install debugging

12
README
View file

@ -2,17 +2,17 @@ This file is licensed under the terms of the expat license, see the file EXPAT.
Midori is a lightweight web browser. Midori is a lightweight web browser.
* Full integration with GTK+2. * Full integration with GTK+2 and GTK+3.
* Fast rendering with WebKit. * Fast rendering with WebKit and HTML5 video with GStreamer.
* Tabs, windows and session management. * Tabs, windows and session management.
* Flexibly configurable Web Search. * History completion and configurable Web Search.
* User scripts and user styles support. * User scripts and user styles support.
* Adblock Plus compatible, external download manager support.
* Straightforward bookmark management. * Straightforward bookmark management.
* Customizable and extensible interface. * Customizable interface, extensions written in C and Vala.
* Extensions written in C.
Requirements: GLib 2.22, GTK+ 2.10, WebkitGTK+ 1.1.17, libXML2, Requirements: GLib 2.22, GTK+ 2.10, WebkitGTK+ 1.1.17, libXML2,
libsoup 2.27.90, sqlite 3.0, Vala 0.10 libsoup 2.27.90, sqlite 3.0, Vala 0.14
Optional: GTK+ 3.0, Unique 0.9, libnotify Optional: GTK+ 3.0, Unique 0.9, libnotify

2
configure vendored
View file

@ -130,7 +130,7 @@ clean:
distclean: distclean:
@$WAF distclean @$WAF distclean
@-rm -rf _build_ @-rm -rf _build
@-rm -f Makefile @-rm -f Makefile
check: check:

View file

@ -186,10 +186,10 @@ AutoSuggestControl.prototype.init = function () {
}; };
//assign onblur event handler (hides suggestions) //assign onblur event handler (hides suggestions)
this.textbox.onblur = if (!this.textbox.onblur)
this.textbox.onclick = function () { this.textbox.onblur = function () { oThis.hideSuggestions(); };
oThis.hideSuggestions(); if (!this.textbox.onclick)
}; this.textbox.onclick = function () { oThis.hideSuggestions(); };
//create the suggestions dropdown //create the suggestions dropdown
this.createDropDown(); this.createDropDown();
@ -299,7 +299,7 @@ function initSuggestions () {
if (inputs.length == 0) if (inputs.length == 0)
return false; return false;
for (i=0;i<inputs.length;i++) for (var i=0;i<inputs.length;i++)
{ {
var ename = inputs[i].getAttribute("name"); var ename = inputs[i].getAttribute("name");
var eid = inputs[i].getAttribute("id"); var eid = inputs[i].getAttribute("id");

View file

@ -7,7 +7,7 @@
<title>midori:faq</title> <title>midori:faq</title>
<meta name="generator" content="DokuWiki"/> <meta name="generator" content="DokuWiki"/>
<meta name="robots" content="noindex,nofollow"/> <meta name="robots" content="noindex,nofollow"/>
<meta name="date" content="2011-11-08T02:51:30+0100"/> <meta name="date" content="2012-03-18T00:07:24+0100"/>
<meta name="keywords" content="midori,faq"/> <meta name="keywords" content="midori,faq"/>
<link rel="search" type="application/opensearchdescription+xml" href="/lib/exe/opensearch.php" title="Xfce Wiki"/> <link rel="search" type="application/opensearchdescription+xml" href="/lib/exe/opensearch.php" title="Xfce Wiki"/>
<link rel="start" href="/"/> <link rel="start" href="/"/>
@ -19,9 +19,9 @@
<link rel="canonical" href="http://wiki.xfce.org/midori/faq"/> <link rel="canonical" href="http://wiki.xfce.org/midori/faq"/>
<link rel="stylesheet" type="text/css" href="faq.css" /> <link rel="stylesheet" type="text/css" href="faq.css" />
<script type="text/javascript"><!--//--><![CDATA[//><!-- <script type="text/javascript"><!--//--><![CDATA[//><!--
var NS='midori';var SIG=' --- //[[christian@twotoasts.de|Christian Dywan]] 2011/11/11 00:07//';var JSINFO = {"id":"midori:faq","namespace":"midori"}; var NS='midori';var JSINFO = {"id":"midori:faq","namespace":"midori"};
//--><!]]></script> //--><!]]></script>
<script type="text/javascript" charset="utf-8" src="/lib/exe/js.php?tseed=1316333533"></script> <script type="text/javascript" charset="utf-8" src="/lib/exe/js.php?tseed=1330500193"></script>
</head> </head>
<body> <body>
<div class="dokuwiki export"> <div class="dokuwiki export">
@ -32,31 +32,33 @@ var NS='midori';var SIG=' --- //[[christian@twotoasts.de|Christian Dywan]] 2011/
<ul class="toc"> <ul class="toc">
<li class="level1"><div class="li"><span class="li"><a href="#midori_-_frequently_asked_questions" class="toc">Midori - Frequently asked questions</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#midori_-_frequently_asked_questions" class="toc">Midori - Frequently asked questions</a></span></div></li>
<li class="level1"><div class="li"><span class="li"><a href="#getting_started" class="toc">Getting started</a></span></div> <li class="level1"><div class="li"><span class="li"><a href="#getting_started" class="toc">Getting started</a></span></div></li>
<li class="level1"><div class="li"><span class="li"><a href="#common_problems" class="toc">Common problems</a></span></div>
<ul class="toc"> <ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#about_midori" class="toc">About Midori</a></span></div></li> <li class="level2"><div class="li"><span class="li"><a href="#flash_doesn_t_work" class="toc">Flash doesn&#039;t work</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#common_problems" class="toc">Common problems</a></span></div></li>
</ul> </ul>
</li> </li>
<li class="level1"><div class="li"><span class="li"><a href="#features" class="toc">Features</a></span></div> <li class="level1"><div class="li"><span class="li"><a href="#privacy" class="toc">Privacy</a></span></div>
<ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#blacklist_cookies" class="toc">Blacklist cookies</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#adblock" class="toc">Adblock</a></span></div></li>
</ul>
</li>
<li class="level1"><div class="li"><span class="li"><a href="#modes" class="toc">Modes</a></span></div>
<ul class="toc"> <ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#web_applications" class="toc">Web Applications</a></span></div></li> <li class="level2"><div class="li"><span class="li"><a href="#web_applications" class="toc">Web Applications</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#private_browsing" class="toc">Private Browsing</a></span></div></li> <li class="level2"><div class="li"><span class="li"><a href="#private_browsing" class="toc">Private Browsing</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#proxy_servers" class="toc">Proxy servers</a></span></div></li> <li class="level2"><div class="li"><span class="li"><a href="#kiosk_mode" class="toc">Kiosk mode</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#using_the_keyboard" class="toc">Using the Keyboard</a></span></div>
<ul class="toc">
<li class="level3"><div class="li"><span class="li"><a href="#hjkl" class="toc">HJKL</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#following_links" class="toc">Following Links</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#use_ctrl_shift_tab_to_switch_between_pages" class="toc">Use Ctrl(+Shift)+Tab to switch between pages</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#customizing_keyboard_shortcuts" class="toc">Customizing keyboard shortcuts</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#using_find" class="toc">Using Find</a></span></div></li>
</ul> </ul>
</li> </li>
<li class="level2"><div class="li"><span class="li"><a href="#mouse_gestures" class="toc">Mouse Gestures</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#proxy_servers" class="toc">Proxy servers</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#spell_check" class="toc">Spell check</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#keyboard_hotkeys" class="toc">Keyboard Hotkeys</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#user_scripts" class="toc">User scripts</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#mouse_gestures" class="toc">Mouse Gestures</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#user_styles" class="toc">User styles</a></span></div></li></ul> <li class="level1"><div class="li"><span class="li"><a href="#user_scripts_and_styles" class="toc">User scripts and styles</a></span></div>
</li></ul> <ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#user_styles" class="toc">User styles</a></span></div></li>
</ul></li>
</ul>
</div> </div>
</div> </div>
<!-- TOC END --> <!-- TOC END -->
@ -131,9 +133,9 @@ Midori and all delivered artwork are licensed under the LGPL2.
</p> </p>
</div> </div>
<!-- EDIT3 SECTION "About Midori" [320-1212] -->
<h2 class="sectionedit4"><a name="common_problems" id="common_problems">Common problems</a></h2> <h1 class="sectionedit3"><a name="common_problems" id="common_problems">Common problems</a></h1>
<div class="level2"> <div class="level1">
</div> </div>
@ -193,6 +195,12 @@ Use a smaller toolbar:
</p> </p>
<pre class="code">gtk-toolbar-icon-size = GTK_ICON_SIZE_SMALL_TOOLBAR</pre> <pre class="code">gtk-toolbar-icon-size = GTK_ICON_SIZE_SMALL_TOOLBAR</pre>
<p>
Only for those not running a complete DE like Xfce, Elementary, etc…<br/>
There is a preference: Preferences → Browsing → Toolbar Style: Small icons
</p>
<p> <p>
Enable changing hotkeys while hovering menu items: Enable changing hotkeys while hovering menu items:
</p> </p>
@ -209,7 +217,34 @@ There appears to be an issue with Glib 2.16. The recommended solution is to upgr
</div> </div>
<h4><a name="flashnetscape_plugins_don_t_work" id="flashnetscape_plugins_don_t_work">Flash/ Netscape plugins don&#039;t work</a></h4> <h4><a name="how_can_i_change_the_cache_folder_to_tmpfs" id="how_can_i_change_the_cache_folder_to_tmpfs">How can I change the cache folder (to tmpfs)?</a></h4>
<div class="level4">
<p>
On Linux and BSD, you can set XDG_CACHE_HOME for all applications, or just Midori. Midori saves icons and cache files in that location. The default is ~/.cache.
</p>
<p>
export XDG_CACHE_HOME=/dev/shm
</p>
</div>
<h2 class="sectionedit4"><a name="flash_doesn_t_work" id="flash_doesn_t_work">Flash doesn&#039;t work</a></h2>
<div class="level2">
</div>
<h4><a name="windows_support" id="windows_support">Windows support</a></h4>
<div class="level4">
<p>
WebKitGTK+ and thusly Midori on Windows doesn&#039;t support Flash or any other plugins. If WebKitGTK+ adds the feature in the future, we will support it. For now there&#039;s nothing we can do.
</p>
</div>
<h4><a name="netscape_plugins_on_linux_bsd_and_os_x" id="netscape_plugins_on_linux_bsd_and_os_x">Netscape plugins on Linux, BSD and OS X</a></h4>
<div class="level4"> <div class="level4">
<p> <p>
@ -266,8 +301,6 @@ You need to have GStreamer plugins installed which implement the codecs.
</li> </li>
<li class="level1"><div class="li"> You may need gstreamer0.10-alsa for ALSA, depending on your distribution.</div> <li class="level1"><div class="li"> You may need gstreamer0.10-alsa for ALSA, depending on your distribution.</div>
</li> </li>
<li class="level1"><div class="li"> With Arch Linux, you may need to install liboil explicitly if it is not installed already (see <a href="https://bugs.archlinux.org/task/20945" class="urlextern" title="https://bugs.archlinux.org/task/20945" rel="nofollow">this</a> bug report).</div>
</li>
<li class="level1"><div class="li"> You need plugins for Theora, gstreamer0.10-base and <acronym title="Moving Picture Experts Group">MPEG</acronym>-4 incluing aac (e.g. gst-plugins-faad), gstreamer0.10-bad. For WebM, you&#039;ll need plugins for vorbis (-base), matroska (-good), and vp8 (-bad). Have a look at <a href="http://www.gstreamer.net/documentation/plugins.html" class="urlextern" title="http://www.gstreamer.net/documentation/plugins.html" rel="nofollow">http://www.gstreamer.net/documentation/plugins.html</a> for details.</div> <li class="level1"><div class="li"> You need plugins for Theora, gstreamer0.10-base and <acronym title="Moving Picture Experts Group">MPEG</acronym>-4 incluing aac (e.g. gst-plugins-faad), gstreamer0.10-bad. For WebM, you&#039;ll need plugins for vorbis (-base), matroska (-good), and vp8 (-bad). Have a look at <a href="http://www.gstreamer.net/documentation/plugins.html" class="urlextern" title="http://www.gstreamer.net/documentation/plugins.html" rel="nofollow">http://www.gstreamer.net/documentation/plugins.html</a> for details.</div>
</li> </li>
<li class="level1"><div class="li"> For Youtube or Vimeo, you need WebKitGTK+ 1.1.20 or newer.</div> <li class="level1"><div class="li"> For Youtube or Vimeo, you need WebKitGTK+ 1.1.20 or newer.</div>
@ -293,36 +326,6 @@ icedtea6 version 1.8 and above has been known to crash midori. If this is the c
</div> </div>
<h4><a name="are_socks_proxy_servers_supported" id="are_socks_proxy_servers_supported">Are SOCKS proxy servers supported?</a></h4>
<div class="level4">
<p>
Currently only <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> proxy servers are supported directly. A way to use SOCKS on Unix is to use tsocks with <acronym title="Secure Shell">SSH</acronym> as follows:
</p>
<ol>
<li class="level1"><div class="li"> Install &#039;tsocks&#039;</div>
</li>
<li class="level1"><div class="li"> Open /etc/tsocks.conf in an editor</div>
</li>
<li class="level1"><div class="li"> Type something like this, you can choose the port freely: <pre class="code">server = 127.0.0.1
server_type = 5
server_port = 5555</pre>
</div>
</li>
<li class="level1"><div class="li"> Open an <acronym title="Secure Shell">SSH</acronym> connection with the same port: <pre class="code"> ssh -D localhost:5555 myhost.com </pre>
</div>
</li>
<li class="level1"><div class="li"> Run Midori with “tsocks” in front of it: <pre class="code"> tsocks midori </pre>
</div>
</li>
<li class="level1"><div class="li"> Now you can use for example <a href="http://www.whatsmyip.org/" class="urlextern" title="http://www.whatsmyip.org/" rel="nofollow">http://www.whatsmyip.org/</a> to verify that you are using a SOCKS connection. The IP address should match the one of your <acronym title="Secure Shell">SSH</acronym> host. Remember to keep the <acronym title="Secure Shell">SSH</acronym> login running, and don&#039;t suspend it, otherwise it won&#039;t work.</div>
</li>
<li class="level1"><div class="li"> If the connection fails for some reason, you should see a connection error.</div>
</li>
</ol>
</div>
<h4><a name="how_do_i_get_rid_of_the_menubar" id="how_do_i_get_rid_of_the_menubar">How do I get rid of the menubar?</a></h4> <h4><a name="how_do_i_get_rid_of_the_menubar" id="how_do_i_get_rid_of_the_menubar">How do I get rid of the menubar?</a></h4>
<div class="level4"> <div class="level4">
@ -431,25 +434,79 @@ As of git 2011-03-05 02:40:00 UTC and Midori 0.3.3 you can
<p> <p>
Add a line to ~/.local/share/applications/mimeapps.list: Add a line to ~/.local/share/applications/mimeapps.list:
</p> </p>
<pre class="code"> x-scheme-handler/magnet=transmission-gtk.desktop</pre> <pre class="code">x-scheme-handler/magnet=transmission-gtk.desktop</pre>
<p> <p>
Or install an application which advertises the scheme like so: Or install an application which advertises the scheme like so:
</p> </p>
<pre class="code"> MimeType=x-scheme-handler/magnet;</pre> <pre class="code">MimeType=x-scheme-handler/magnet;</pre>
<p> <p>
Note that incomplete .desktop files will silently fail and it will look as if it doesn&#039;t exist. Note that incomplete .desktop files will silently fail and it will look as if it doesn&#039;t exist.
</p> </p>
</div> </div>
<!-- EDIT4 SECTION "Common problems" [1213-8946] -->
<h1 class="sectionedit5"><a name="features" id="features">Features</a></h1> <h4><a name="spell_check" id="spell_check">Spell check</a></h4>
<div class="level4">
<p>
First enable spell checking:
Edit→Preferences→Behavior and check “Enable Spell Checking”.
</p>
<p>
Now while typing any errors should get underlined in red. To get suggestions, highlight the word and right-click. Should see a list of suggestions on the top of the menu.
</p>
</div>
<h1 class="sectionedit5"><a name="privacy" id="privacy">Privacy</a></h1>
<div class="level1"> <div class="level1">
</div> </div>
<!-- EDIT5 SECTION "Features" [8947-8969] -->
<h2 class="sectionedit6"><a name="web_applications" id="web_applications">Web Applications</a></h2> <h2 class="sectionedit6"><a name="blacklist_cookies" id="blacklist_cookies">Blacklist cookies</a></h2>
<div class="level2">
<p>
As of Midori 0.4.4 you can add a hidden option to ~/.config/midori/config like so:
</p>
<pre class="code">site-data-rules=-google.com,-facebook.com,!bugzilla.gnome.org,+bugs.launchpad.net</pre>
<ol>
<li class="level1"><div class="li"> Values prefixed with ”-” are always blocked</div>
</li>
<li class="level1"><div class="li"> Values prefixed with ”+” are always accepted</div>
</li>
<li class="level1"><div class="li"> Values prefixed with ”!” are not cleared in Clear Private Data</div>
</li>
<li class="level1"><div class="li"> No wildcards.</div>
</li>
<li class="level1"><div class="li"> LSO, local storage and application caches ignore all policies.</div>
</li>
</ol>
<p>
The feature is currently experimental and will change in future versions.
</p>
</div>
<h2 class="sectionedit7"><a name="adblock" id="adblock">Adblock</a></h2>
<div class="level2">
<p>
The Advertisement Blocker can be activated under Extensions. It uses the same lists as Adblock Plus. URLs are blocked completely and never loaded. Lists can be added through the option button on the right side in the extension list.
</p>
</div>
<h1 class="sectionedit8"><a name="modes" id="modes">Modes</a></h1>
<div class="level1">
</div>
<h2 class="sectionedit9"><a name="web_applications" id="web_applications">Web Applications</a></h2>
<div class="level2"> <div class="level2">
<p> <p>
@ -469,13 +526,13 @@ There are two closely related features to open websites as dedicated windows of
</p> </p>
</div> </div>
<!-- EDIT6 SECTION "Web Applications" [8970-9486] -->
<h2 class="sectionedit7"><a name="private_browsing" id="private_browsing">Private Browsing</a></h2> <h2 class="sectionedit10"><a name="private_browsing" id="private_browsing">Private Browsing</a></h2>
<div class="level2"> <div class="level2">
<ol>
<li class="level1"><div class="li"> File menu/ App Menu button → Private Browsing</div> <p>
</li> File menu/ App Menu button → Private Browsing
</ol> </p>
<p> <p>
A private window is a separate process, so crashes don&#039;t affect the normal browser session. No sensitive data such as cookies, history or bookmarks are stored. No extensions are loaded. Panels are not available. A private window is a separate process, so crashes don&#039;t affect the normal browser session. No sensitive data such as cookies, history or bookmarks are stored. No extensions are loaded. Panels are not available.
@ -495,10 +552,42 @@ The same options available to -a/ app can be used for private browsing mode.
</p> </p>
</div> </div>
<!-- EDIT7 SECTION "Private Browsing" [9487-10410] -->
<h2 class="sectionedit8"><a name="proxy_servers" id="proxy_servers">Proxy servers</a></h2> <h2 class="sectionedit11"><a name="kiosk_mode" id="kiosk_mode">Kiosk mode</a></h2>
<div class="level2"> <div class="level2">
<p>
There is no specific mode, instead you use several command line switches. A typical fullscreen setup with no toolbar that opens about:blank and resets the session after 2 minutes of inactivity for instance:
</p>
<pre class="code bash">midori <span class="re5">-i</span> <span class="nu0">120</span> <span class="re5">-e</span> Fullscreen <span class="re5">-e</span> Navigationbar <span class="re5">-a</span> about:blank</pre>
<p>
Available commands for -e can be listed with “midori help-execute”.
</p>
<p>
If needed, a customized profile can be created with “midori -c /path/to/folder”. Using the shortcut editor extension, keyboard shortcuts can be removed as needed. Afterwards just append ”-c /path/to/folder” to the kiosk mode command line.
</p>
<p>
To restrict pages that can be opened, you can use a regular expression. The expression is a blacklist. To block undesirable sites you can do something like:
</p>
<pre class="code bash"><span class="re5">-b</span> <span class="st_h">'youtube|youporn'</span></pre>
<p>
By negating the expression you can also whitelist pages.
</p>
<pre class="code bash"><span class="re5">-b</span> <span class="st_h">'^(?!.*?(gmail|mail\.google|accounts\.google)).*'</span></pre>
<p>
Any links outside end up in an error page. All images and other files won&#039;t be loaded.
</p>
</div>
<h1 class="sectionedit12"><a name="proxy_servers" id="proxy_servers">Proxy servers</a></h1>
<div class="level1">
<p> <p>
By running a local proxy you can modify web content even before it has reached Midori. That allows you to do things similar to what user scripts and user styles provide and even others that neither is suitable for. By running a local proxy you can modify web content even before it has reached Midori. That allows you to do things similar to what user scripts and user styles provide and even others that neither is suitable for.
</p> </p>
@ -545,14 +634,44 @@ Mousehole is a scriptable proxy server written in Ruby.
</p> </p>
</div> </div>
<!-- EDIT8 SECTION "Proxy servers" [10411-11241] -->
<h2 class="sectionedit9"><a name="using_the_keyboard" id="using_the_keyboard">Using the Keyboard</a></h2> <h4><a name="are_socks_proxy_servers_supported" id="are_socks_proxy_servers_supported">Are SOCKS proxy servers supported?</a></h4>
<div class="level2"> <div class="level4">
<p>
Currently only <acronym title="Hyper Text Transfer Protocol">HTTP</acronym> proxy servers are supported directly. A way to use SOCKS on Unix is to use tsocks with <acronym title="Secure Shell">SSH</acronym> as follows:
</p>
<ol>
<li class="level1"><div class="li"> Install &#039;tsocks&#039;</div>
</li>
<li class="level1"><div class="li"> Open /etc/tsocks.conf in an editor</div>
</li>
<li class="level1"><div class="li"> Type something like this, you can choose the port freely: <pre class="code">server = 127.0.0.1
server_type = 5
server_port = 5555</pre>
</div>
</li>
<li class="level1"><div class="li"> Open an <acronym title="Secure Shell">SSH</acronym> connection with the same port: <pre class="code"> ssh -D localhost:5555 myhost.com </pre>
</div>
</li>
<li class="level1"><div class="li"> Run Midori with “tsocks” in front of it: <pre class="code"> tsocks midori </pre>
</div>
</li>
<li class="level1"><div class="li"> Now you can use for example <a href="http://www.whatsmyip.org/" class="urlextern" title="http://www.whatsmyip.org/" rel="nofollow">http://www.whatsmyip.org/</a> to verify that you are using a SOCKS connection. The IP address should match the one of your <acronym title="Secure Shell">SSH</acronym> host. Remember to keep the <acronym title="Secure Shell">SSH</acronym> login running, and don&#039;t suspend it, otherwise it won&#039;t work.</div>
</li>
<li class="level1"><div class="li"> If the connection fails for some reason, you should see a connection error.</div>
</li>
</ol>
</div> </div>
<!-- EDIT9 SECTION "Using the Keyboard" [11242-11273] -->
<h3 class="sectionedit10"><a name="hjkl" id="hjkl">HJKL</a></h3> <h1 class="sectionedit13"><a name="keyboard_hotkeys" id="keyboard_hotkeys">Keyboard Hotkeys</a></h1>
<div class="level3"> <div class="level1">
</div>
<h4><a name="hjkl" id="hjkl">HJKL</a></h4>
<div class="level4">
<p> <p>
You can use the Vim-like key bindings [hjkl] to navigate a page. h=left j=down k=up l=right In a picture: You can use the Vim-like key bindings [hjkl] to navigate a page. h=left j=down k=up l=right In a picture:
@ -566,9 +685,9 @@ You can also use the arrow keys to do the same.
</p> </p>
</div> </div>
<!-- EDIT10 SECTION "HJKL" [11274-11481] -->
<h3 class="sectionedit11"><a name="following_links" id="following_links">Following Links</a></h3> <h4><a name="following_links" id="following_links">Following Links</a></h4>
<div class="level3"> <div class="level4">
<p> <p>
To enable Hints in Midori [similar to those vimperator provides in Firefox], press . To enable Hints in Midori [similar to those vimperator provides in Firefox], press .
@ -579,9 +698,9 @@ With hints enabled, type the link number, and press Enter to open the link in th
</p> </p>
</div> </div>
<!-- EDIT11 SECTION "Following Links" [11482-11813] -->
<h3 class="sectionedit12"><a name="use_ctrl_shift_tab_to_switch_between_pages" id="use_ctrl_shift_tab_to_switch_between_pages">Use Ctrl(+Shift)+Tab to switch between pages</a></h3> <h4><a name="use_ctrl_shift_tab_to_switch_between_pages" id="use_ctrl_shift_tab_to_switch_between_pages">Use Ctrl(+Shift)+Tab to switch between pages</a></h4>
<div class="level3"> <div class="level4">
<p> <p>
Since Midori 0.3.5 Ctrl+Tab is supported by default. Since Midori 0.3.5 Ctrl+Tab is supported by default.
@ -592,18 +711,18 @@ In older versions you can enable the History List extension under Tools → Exte
</p> </p>
</div> </div>
<!-- EDIT12 SECTION "Use Ctrl(+Shift)+Tab to switch between pages" [11814-12012] -->
<h3 class="sectionedit13"><a name="customizing_keyboard_shortcuts" id="customizing_keyboard_shortcuts">Customizing keyboard shortcuts</a></h3> <h4><a name="customizing_keyboard_shortcuts" id="customizing_keyboard_shortcuts">Customizing keyboard shortcuts</a></h4>
<div class="level3"> <div class="level4">
<p> <p>
Enable the Shortcuts extension Tools → Extensions. To edit a keybinding Tools → Customize Shortcuts… Enable the Shortcuts extension Tools → Extensions. To edit a keybinding Tools → Customize Shortcuts…
</p> </p>
</div> </div>
<!-- EDIT13 SECTION "Customizing keyboard shortcuts" [12013-12162] -->
<h3 class="sectionedit14"><a name="using_find" id="using_find">Using Find</a></h3> <h4><a name="using_find" id="using_find">Using Find</a></h4>
<div class="level3"> <div class="level4">
<p> <p>
Default shortcuts for Find are: Default shortcuts for Find are:
@ -612,7 +731,7 @@ Default shortcuts for Find are:
<p> <p>
Find: Ctrl+f ”/” and ”,”<br/> Find: Ctrl+f ”/” and ”,”<br/>
FindNext: Ctrl+g<br/> FindNext: Ctrl+g and Enter<br/>
FindPrevious: Shift+Ctrl+g<br/> FindPrevious: Shift+Ctrl+g<br/>
@ -627,9 +746,9 @@ When using Ctrl+f to bring up Find, use Ctrl+f again or ESC. When using ”/”
</p> </p>
</div> </div>
<!-- EDIT14 SECTION "Using Find" [12163-12579] -->
<h2 class="sectionedit15"><a name="mouse_gestures" id="mouse_gestures">Mouse Gestures</a></h2> <h1 class="sectionedit14"><a name="mouse_gestures" id="mouse_gestures">Mouse Gestures</a></h1>
<div class="level2"> <div class="level1">
<p> <p>
By default the right mouse button initiates gestures. By default the right mouse button initiates gestures.
@ -657,28 +776,9 @@ Additionally, there are programs allowing mouse gestures system-wide, for exampl
</p> </p>
</div> </div>
<!-- EDIT15 SECTION "Mouse Gestures" [12580-13253] -->
<h2 class="sectionedit16"><a name="spell_check" id="spell_check">Spell check</a></h2>
<div class="level2">
<p> <h1 class="sectionedit15"><a name="user_scripts_and_styles" id="user_scripts_and_styles">User scripts and styles</a></h1>
First enable spell checking: <div class="level1">
Edit→Preferences→Behavior and check “Enable Spell Checking”.
</p>
<p>
Now while typing any errors should get underlined in red. To get suggestions, highlight the word and right-click. Should see a list of suggestions on the top of the menu.
</p>
</div>
<!-- EDIT16 SECTION "Spell check" [13254-13543] -->
<h2 class="sectionedit17"><a name="user_scripts" id="user_scripts">User scripts</a></h2>
<div class="level2">
</div>
<h4><a name="overview" id="overview">Overview</a></h4>
<div class="level4">
<p> <p>
UserScripts are scripts applied on some, or on all web pages. They can modify pages locally to add or alter functionality. That includes fixing bugs in web pages. User scripts are also available in other browsers, in the form of <a href="http://www.greasespot.net" class="urlextern" title="http://www.greasespot.net" rel="nofollow">Mozilla&#039;s Greasemonkey</a> or <a href="http://www.opera.com/support/tutorials/userjs/" class="urlextern" title="http://www.opera.com/support/tutorials/userjs/" rel="nofollow">Opera&#039;s User JavaScript</a>. UserScripts are scripts applied on some, or on all web pages. They can modify pages locally to add or alter functionality. That includes fixing bugs in web pages. User scripts are also available in other browsers, in the form of <a href="http://www.greasespot.net" class="urlextern" title="http://www.greasespot.net" rel="nofollow">Mozilla&#039;s Greasemonkey</a> or <a href="http://www.opera.com/support/tutorials/userjs/" class="urlextern" title="http://www.opera.com/support/tutorials/userjs/" rel="nofollow">Opera&#039;s User JavaScript</a>.
@ -737,15 +837,10 @@ You can also use <a href="http://rightfootin.blogspot.com/2009/04/flashblock-wan
</p> </p>
</div> </div>
<!-- EDIT17 SECTION "User scripts" [13544-16104] -->
<h2 class="sectionedit18"><a name="user_styles" id="user_styles">User styles</a></h2> <h2 class="sectionedit16"><a name="user_styles" id="user_styles">User styles</a></h2>
<div class="level2"> <div class="level2">
</div>
<h4><a name="overview1" id="overview1">Overview</a></h4>
<div class="level4">
<p> <p>
User styles are <acronym title="Cascading Style Sheets">CSS</acronym> 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. User styles are <acronym title="Cascading Style Sheets">CSS</acronym> 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.
</p> </p>

View file

@ -6,18 +6,20 @@ import pproc as subprocess
import os import os
import Utils import Utils
blddir = '_build' # recognized by ack
for module in ('midori', 'katze'): for module in ('midori', 'katze'):
try: try:
if not os.access ('_build_', os.F_OK): if not os.access (blddir, os.F_OK):
Utils.check_dir ('_build_') Utils.check_dir (blddir)
if not os.access ('_build_/docs', os.F_OK): if not os.access (blddir + '/docs', os.F_OK):
Utils.check_dir ('_build_/docs') Utils.check_dir (blddir + '/docs')
if not os.access ('_build_/docs/api', os.F_OK): if not os.access (blddir + '/docs/api', os.F_OK):
Utils.check_dir ('_build_/docs/api') Utils.check_dir (blddir + '/docs/api')
subprocess.call (['gtkdoc-scan', '--module=' + module, 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']) '--rebuild-sections', '--rebuild-types'])
os.chdir ('_build_/docs/api/' + module) os.chdir (blddir + '/docs/api/' + module)
subprocess.call (['gtkdoc-mktmpl', '--module=' + module, subprocess.call (['gtkdoc-mktmpl', '--module=' + module,
'--output-dir=.' + module]) '--output-dir=.' + module])
subprocess.call (['gtkdoc-mkdb', '--module=' + module, subprocess.call (['gtkdoc-mkdb', '--module=' + module,

View file

@ -39,6 +39,7 @@ static GHashTable* keys = NULL;
static GHashTable* optslist = NULL; static GHashTable* optslist = NULL;
static GHashTable* urlcache = NULL; static GHashTable* urlcache = NULL;
static GHashTable* blockcssprivate = NULL; static GHashTable* blockcssprivate = NULL;
static GHashTable* navigationwhitelist = NULL;
static GString* blockcss = NULL; static GString* blockcss = NULL;
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
static guint debug; static guint debug;
@ -127,6 +128,8 @@ adblock_destroy_db ()
urlcache = NULL; urlcache = NULL;
g_hash_table_destroy (blockcssprivate); g_hash_table_destroy (blockcssprivate);
blockcssprivate = NULL; blockcssprivate = NULL;
g_hash_table_destroy (navigationwhitelist);
navigationwhitelist = NULL;
} }
static void static void
@ -147,6 +150,9 @@ adblock_init_db ()
blockcssprivate = g_hash_table_new_full (g_str_hash, g_str_equal, blockcssprivate = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free, (GDestroyNotify)g_free,
(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) if (blockcss && blockcss->len > 0)
g_string_free (blockcss, TRUE); g_string_free (blockcss, TRUE);
@ -779,6 +785,23 @@ adblock_prepare_urihider_js (GList* uris)
return g_string_free (js, FALSE); 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 static void
adblock_resource_request_starting_cb (WebKitWebView* web_view, adblock_resource_request_starting_cb (WebKitWebView* web_view,
WebKitWebFrame* web_frame, WebKitWebFrame* web_frame,
@ -798,6 +821,10 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
return; return;
req_uri = webkit_network_request_get_uri (request); 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) if (!midori_uri_is_http (req_uri)
|| g_str_has_suffix (req_uri, "favicon.ico")) || g_str_has_suffix (req_uri, "favicon.ico"))
return; return;
@ -806,6 +833,15 @@ adblock_resource_request_starting_cb (WebKitWebView* web_view,
if (!(msg && !g_strcmp0 (msg->method, "GET"))) if (!(msg && !g_strcmp0 (msg->method, "GET")))
return; 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 #ifdef G_ENABLE_DEBUG
if (debug == 2) if (debug == 2)
g_test_timer_start (); 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 = g_build_filename (midori_extension_get_config_dir (extension),
CUSTOM_LIST_NAME, NULL); 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); g_fprintf (list, "%s\n", gtk_entry_get_text (GTK_ENTRY (entry)));
return; fclose (list);
adblock_reload_rules (extension, TRUE);
g_debug ("%s: Updated custom list\n", G_STRFUNC);
} }
else
g_fprintf (list, "%s\n", gtk_entry_get_text (GTK_ENTRY (entry))); g_debug ("%s: Failed to open custom list %s\n", G_STRFUNC, custom_list);
fclose (list);
adblock_reload_rules (extension, TRUE);
g_free (custom_list); g_free (custom_list);
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
} }
@ -983,6 +1019,8 @@ adblock_add_tab_cb (MidoriBrowser* browser,
g_signal_connect_after (web_view, "populate-popup", g_signal_connect_after (web_view, "populate-popup",
G_CALLBACK (adblock_populate_popup_cb), extension); 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_signal_connect (web_view, "resource-request-starting",
G_CALLBACK (adblock_resource_request_starting_cb), image); G_CALLBACK (adblock_resource_request_starting_cb), image);
g_signal_connect (web_view, "load-finished", g_signal_connect (web_view, "load-finished",
@ -990,16 +1028,17 @@ adblock_add_tab_cb (MidoriBrowser* browser,
} }
static void static void
adblock_deactivate_cb (MidoriExtension* extension, adblock_remove_tab_cb (MidoriBrowser* browser,
MidoriBrowser* browser); MidoriView* view,
MidoriExtension* extension)
{
GtkWidget* web_view = midori_view_get_web_view (view);
g_hash_table_remove (navigationwhitelist, web_view);
}
static void static void
adblock_add_tab_foreach_cb (MidoriView* view, adblock_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser, MidoriBrowser* browser);
MidoriExtension* extension)
{
adblock_add_tab_cb (browser, view, extension);
}
static void static void
adblock_app_add_browser_cb (MidoriApp* app, adblock_app_add_browser_cb (MidoriApp* app,
@ -1008,6 +1047,8 @@ adblock_app_add_browser_cb (MidoriApp* app,
{ {
GtkWidget* statusbar; GtkWidget* statusbar;
GtkWidget* image; GtkWidget* image;
GtkWidget* view;
gint i;
statusbar = katze_object_get_object (browser, "statusbar"); statusbar = katze_object_get_object (browser, "statusbar");
image = NULL; image = NULL;
@ -1017,10 +1058,14 @@ adblock_app_add_browser_cb (MidoriApp* app,
g_object_set_data_full (G_OBJECT (browser), "status-image", image, g_object_set_data_full (G_OBJECT (browser), "status-image", image,
(GDestroyNotify)gtk_widget_destroy); (GDestroyNotify)gtk_widget_destroy);
midori_browser_foreach (browser, i = 0;
(GtkCallback)adblock_add_tab_foreach_cb, extension); 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_signal_connect (browser, "add-tab",
G_CALLBACK (adblock_add_tab_cb), extension); 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_signal_connect (extension, "open-preferences",
G_CALLBACK (adblock_open_preferences_cb), extension); G_CALLBACK (adblock_open_preferences_cb), extension);
g_signal_connect (extension, "deactivate", g_signal_connect (extension, "deactivate",
@ -1284,7 +1329,7 @@ adblock_frame_add_private (const gchar* line,
/* Ignore Firefox-specific option */ /* Ignore Firefox-specific option */
if (!g_strcmp0 (domain, "~pregecko2")) if (!g_strcmp0 (domain, "~pregecko2"))
continue; continue;
/* strip ~ from domain */ /* FIXME: ~ should negate match */
if (domain[0] == '~') if (domain[0] == '~')
domain++; domain++;
adblock_update_css_hash (g_strstrip (domain), data[1]); adblock_update_css_hash (g_strstrip (domain), data[1]);
@ -1301,6 +1346,88 @@ adblock_frame_add_private (const gchar* line,
static gchar* static gchar*
adblock_parse_line (gchar* line) 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 */ /* Skip invalid, empty and comment lines */
if (!(line && line[0] != ' ' && line[0] != '!' && line[0])) if (!(line && line[0] != ' ' && line[0] != '!' && line[0]))
return NULL; return NULL;
@ -1376,8 +1503,6 @@ adblock_deactivate_tabs (MidoriView* view,
GtkWidget* web_view = midori_view_get_web_view (view); GtkWidget* web_view = midori_view_get_web_view (view);
GtkWidget* image = g_object_get_data (G_OBJECT (browser), "status-image"); 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 ( g_signal_handlers_disconnect_by_func (
web_view, adblock_window_object_cleared_cb, 0); web_view, adblock_window_object_cleared_cb, 0);
g_signal_handlers_disconnect_by_func ( g_signal_handlers_disconnect_by_func (
@ -1386,12 +1511,16 @@ adblock_deactivate_tabs (MidoriView* view,
web_view, adblock_resource_request_starting_cb, image); web_view, adblock_resource_request_starting_cb, image);
g_signal_handlers_disconnect_by_func ( g_signal_handlers_disconnect_by_func (
web_view, adblock_load_finished_cb, image); web_view, adblock_load_finished_cb, image);
g_signal_handlers_disconnect_by_func (
web_view, adblock_navigation_policy_decision_requested_cb, view);
} }
static void static void
adblock_deactivate_cb (MidoriExtension* extension, adblock_deactivate_cb (MidoriExtension* extension,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
gint i;
GtkWidget* view;
MidoriApp* app = midori_extension_get_app (extension); MidoriApp* app = midori_extension_get_app (extension);
MidoriWebSettings* settings = katze_object_get_object (app, "settings"); MidoriWebSettings* settings = katze_object_get_object (app, "settings");
@ -1403,7 +1532,12 @@ adblock_deactivate_cb (MidoriExtension* extension,
app, adblock_app_add_browser_cb, extension); app, adblock_app_add_browser_cb, extension);
g_signal_handlers_disconnect_by_func ( g_signal_handlers_disconnect_by_func (
browser, adblock_add_tab_cb, extension); 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 (); adblock_destroy_db ();
midori_web_settings_remove_style (settings, "adblock-blockcss"); midori_web_settings_remove_style (settings, "adblock-blockcss");

View file

@ -0,0 +1,218 @@
/*
Copyright (C) 2012 André Stösel <andre@stoesel.de>
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<void*> ("save-as-download") == null
&& download.get_data<void*> ("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<string, GLib.Value?> 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 <andre@stoesel.de>",
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 <andre@stoesel.de>",
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;
}

View file

@ -193,7 +193,7 @@ formhistory_navigation_decision_cb (WebKitWebView* web_view,
The field separator is "|||" */ The field separator is "|||" */
const gchar* script = "function dumpForm (inputs) {" const gchar* script = "function dumpForm (inputs) {"
" var out = '';" " var out = '';"
" for (i=0;i<inputs.length;i++) {" " for (var i = 0; i < inputs.length; i++) {"
" if (inputs[i].getAttribute('autocomplete') == 'off' && " " if (inputs[i].getAttribute('autocomplete') == 'off' && "
" inputs[i].type == 'text')" " inputs[i].type == 'text')"
" continue;" " continue;"
@ -216,7 +216,9 @@ formhistory_navigation_decision_cb (WebKitWebView* web_view,
js_context = webkit_web_frame_get_global_context (web_frame); js_context = webkit_web_frame_get_global_context (web_frame);
value = sokoke_js_script_eval (js_context, script, NULL); value = sokoke_js_script_eval (js_context, script, NULL);
#ifdef FORMHISTORY_USE_GDOM
formhistory_suggestions_hide_cb (NULL, NULL, priv); formhistory_suggestions_hide_cb (NULL, NULL, priv);
#endif
if (value && *value) if (value && *value)
{ {
gchar** inputs = g_strsplit (value, "|||", 0); gchar** inputs = g_strsplit (value, "|||", 0);

View file

@ -419,8 +419,7 @@ tab_panel_browser_add_tab_cb (MidoriBrowser* browser,
GtkWidget* view, GtkWidget* view,
MidoriExtension* extension) MidoriExtension* extension)
{ {
GtkWidget* notebook = katze_object_get_object (browser, "notebook"); gint page = midori_browser_page_num (browser, view);
gint page = gtk_notebook_page_num (GTK_NOTEBOOK (notebook), view);
MidoriWebSettings* settings = midori_browser_get_settings (browser); MidoriWebSettings* settings = midori_browser_get_settings (browser);
gboolean minimized = katze_object_get_boolean (view, "minimized"); gboolean minimized = katze_object_get_boolean (view, "minimized");
GdkPixbuf* icon = midori_view_get_icon (MIDORI_VIEW (view)); GdkPixbuf* icon = midori_view_get_icon (MIDORI_VIEW (view));
@ -468,8 +467,6 @@ tab_panel_browser_add_tab_cb (MidoriBrowser* browser,
g_signal_connect (view, "notify::title", g_signal_connect (view, "notify::title",
G_CALLBACK (tab_panel_view_notify_title_cb), extension); G_CALLBACK (tab_panel_view_notify_title_cb), extension);
} }
g_object_unref (notebook);
} }
static void static void

View file

@ -28,13 +28,16 @@ for extension in extensions:
continue continue
source = extension source = extension
if bld.env['platform'] == 'win32' and target in ['external-download-manager']:
continue
obj = bld.new_task_gen ('cc', 'shlib') obj = bld.new_task_gen ('cc', 'shlib')
obj.target = target obj.target = target
obj.includes = '..' obj.includes = '..'
obj.source = source obj.source = source
obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML HILDON' obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML HILDON'
obj.vapi_dirs = '../midori' obj.vapi_dirs = '../midori ../katze'
obj.packages = 'glib-2.0 gio-2.0 libsoup-2.4 midori' obj.packages = 'glib-2.0 gio-2.0 libsoup-2.4 midori katze'
if bld.env['HAVE_GTK3']: if bld.env['HAVE_GTK3']:
obj.packages += ' gtk+-3.0 webkitgtk-3.0' obj.packages += ' gtk+-3.0 webkitgtk-3.0'
else: else:

View file

@ -331,7 +331,13 @@ proxy_widget_string_destroy_cb (GtkWidget* proxy,
static GList* static GList*
katze_app_info_get_all_for_category (const gchar* category) katze_app_info_get_all_for_category (const gchar* category)
{ {
#ifdef _WIN32
/* FIXME: Real filtering by category would be better */
const gchar* content_type = g_content_type_from_mime_type (category);
GList* all_apps = g_app_info_get_all_for_type (content_type);
#else
GList* all_apps = g_app_info_get_all (); GList* all_apps = g_app_info_get_all ();
#endif
GList* apps = NULL; GList* apps = NULL;
guint i = 0; guint i = 0;
GAppInfo* info; GAppInfo* info;

11
katze/katze.vapi Normal file
View file

@ -0,0 +1,11 @@
/* Copyright (C) 2012 André Stösel <andre@stoesel.de>
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);
}
}

View file

@ -264,8 +264,24 @@ settings_save_to_file (MidoriWebSettings* settings,
{ {
KATZE_ARRAY_FOREACH_ITEM (extension, extensions) KATZE_ARRAY_FOREACH_ITEM (extension, extensions)
if (midori_extension_is_active (extension)) 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); g_object_unref (extensions);
} }
else if ((_extensions = g_object_get_data (G_OBJECT (app), "extensions"))) else if ((_extensions = g_object_get_data (G_OBJECT (app), "extensions")))
@ -441,9 +457,12 @@ midori_history_initialize (KatzeArray* array,
return FALSE; 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, sqlite3_exec (db,
/* "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY" */ "PRAGMA synchronous = NORMAL; PRAGMA temp_store = MEMORY;",
"PRAGMA count_changes = OFF; PRAGMA journal_mode = TRUNCATE;",
NULL, NULL, errmsg); NULL, NULL, errmsg);
if (*errmsg) if (*errmsg)
{ {
@ -964,7 +983,7 @@ midori_soup_session_settings_accept_language_cb (SoupSession* session,
if (stripped_uri != NULL) if (stripped_uri != NULL)
{ {
gchar* stripped_referer; gchar* stripped_referer;
soup_uri_set_path (stripped_uri, NULL); soup_uri_set_path (stripped_uri, "");
soup_uri_set_query (stripped_uri, NULL); soup_uri_set_query (stripped_uri, NULL);
stripped_referer = soup_uri_to_string (stripped_uri, FALSE); stripped_referer = soup_uri_to_string (stripped_uri, FALSE);
soup_uri_free (stripped_uri); soup_uri_free (stripped_uri);
@ -1226,6 +1245,46 @@ midori_load_soup_session_full (gpointer settings)
return FALSE; 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 static gboolean
midori_load_extensions (gpointer data) midori_load_extensions (gpointer data)
{ {
@ -1257,9 +1316,9 @@ midori_load_extensions (gpointer data)
{ {
gchar* fullname; gchar* fullname;
GModule* module; GModule* module;
typedef MidoriExtension* (*extension_init_func)(void); typedef GObject* (*extension_init_func)(void);
extension_init_func extension_init; extension_init_func extension_init;
MidoriExtension* extension = NULL; GObject* extension = NULL;
/* Ignore files which don't have the correct suffix */ /* Ignore files which don't have the correct suffix */
if (!g_str_has_suffix (filename, G_MODULE_SUFFIX)) if (!g_str_has_suffix (filename, G_MODULE_SUFFIX))
@ -1275,11 +1334,22 @@ midori_load_extensions (gpointer data)
extension = extension_init (); extension = extension_init ();
if (extension != NULL) if (extension != NULL)
{ {
/* Signal that we want the extension to load and save */ if (MIDORI_IS_EXTENSION (extension))
g_object_set_data_full (G_OBJECT (extension), "filename", midori_load_extension (app, extensions,
g_strdup (filename), g_free); active_extensions,
if (midori_extension_is_prepared (extension)) MIDORI_EXTENSION (extension), filename);
midori_extension_get_config_dir (extension); 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 (), "description", g_module_error (),
NULL); NULL);
g_warning ("%s", g_module_error ()); 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_object_unref (extension);
} }
g_dir_close (extension_dir); g_dir_close (extension_dir);
@ -1515,7 +1573,8 @@ midori_prepare_uri (const gchar *uri)
if (g_str_has_prefix(uri, "javascript:")) if (g_str_has_prefix(uri, "javascript:"))
return NULL; 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 (); gchar* current_dir = g_get_current_dir ();
uri_ready = g_strconcat ("file://", 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_len (script, json_content, json_length);
g_string_append (script, "); " g_string_append (script, "); "
"var keyfile = '';" "var keyfile = '';"
"for (i in json['shortcuts']) {" "for (var i in json['shortcuts']) {"
"var tile = json['shortcuts'][i];" "var tile = json['shortcuts'][i];"
"keyfile += '[Dial ' + tile['id'].substring (1) + ']\\n'" "keyfile += '[Dial ' + tile['id'].substring (1) + ']\\n'"
" + 'uri=' + tile['href'] + '\\n'" " + 'uri=' + tile['href'] + '\\n'"
@ -1991,10 +2050,14 @@ main (int argc,
return 1; return 1;
} }
/* Relative config path */
if (config && !g_path_is_absolute (config)) if (config && !g_path_is_absolute (config))
{ {
g_critical (_("The specified configuration folder is invalid.")); gchar* old_config = config;
return 1; 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 */ /* Private browsing, window title, default config folder */
@ -2238,6 +2301,7 @@ main (int argc,
g_object_set (settings, g_object_set (settings,
"show-menubar", FALSE, "show-menubar", FALSE,
"show-navigationbar", FALSE, "show-navigationbar", FALSE,
"always-show-tabbar", FALSE,
"toolbar-items", "Back,Forward,ReloadStop,Location,Homepage", "toolbar-items", "Back,Forward,ReloadStop,Location,Homepage",
"show-statusbar", FALSE, "show-statusbar", FALSE,
"enable-developer-extras", FALSE, "enable-developer-extras", FALSE,

View file

@ -68,9 +68,6 @@ struct _MidoriApp
{ {
GObject parent_instance; GObject parent_instance;
MidoriBrowser* browser;
gchar* name;
MidoriWebSettings* settings; MidoriWebSettings* settings;
KatzeArray* bookmarks; KatzeArray* bookmarks;
KatzeArray* trash; KatzeArray* trash;
@ -80,6 +77,7 @@ struct _MidoriApp
KatzeArray* extensions; KatzeArray* extensions;
KatzeArray* browsers; KatzeArray* browsers;
MidoriBrowser* browser;
MidoriAppInstance instance; MidoriAppInstance instance;
#if !HAVE_HILDON || !HAVE_LIBNOTIFY #if !HAVE_HILDON || !HAVE_LIBNOTIFY
@ -87,6 +85,8 @@ struct _MidoriApp
#endif #endif
}; };
static gchar* app_name = NULL;
struct _MidoriAppClass struct _MidoriAppClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
@ -718,29 +718,30 @@ midori_app_create_instance (MidoriApp* app)
GIOChannel* channel; GIOChannel* channel;
#endif #endif
if (!app->name) if (!(display = gdk_display_get_default ()))
return MidoriAppInstanceNull;
{ {
#if HAVE_UNIQUE #if HAVE_UNIQUE
const gchar* config = sokoke_set_config_dir (NULL); const gchar* config = sokoke_set_config_dir (NULL);
gchar* name_hash; gchar* name_hash;
name_hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, config, -1); 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_free (name_hash);
g_object_notify (G_OBJECT (app), "name"); g_object_notify (G_OBJECT (app), "name");
#else #else
app->name = g_strdup (PACKAGE_NAME); katze_assign (app_name, g_strdup (PACKAGE_NAME));
#endif #endif
} }
if (!(display = gdk_display_get_default ()))
return MidoriAppInstanceNull;
display_name = g_strdup (gdk_display_get_name (display)); display_name = g_strdup (gdk_display_get_name (display));
n = strlen (display_name); n = strlen (display_name);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
if (strchr (":.\\/", display_name[i])) if (strchr (":.\\/", display_name[i]))
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 #if HAVE_UNIQUE
instance = unique_app_new (instance_name, NULL); 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); (GIOFunc)midori_app_io_channel_watch_cb, app);
} }
#endif #endif
g_free (instance_name);
g_free (display_name);
#endif #endif
return instance; return instance;
} }
const gchar*
midori_app_get_name (MidoriApp* app)
{
return app_name;
}
static void static void
midori_app_init (MidoriApp* app) midori_app_init (MidoriApp* app)
{ {
@ -793,7 +796,7 @@ midori_app_finalize (GObject* object)
{ {
MidoriApp* app = MIDORI_APP (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->settings, NULL);
katze_object_assign (app->bookmarks, NULL); katze_object_assign (app->bookmarks, NULL);
katze_object_assign (app->trash, NULL); katze_object_assign (app->trash, NULL);
@ -833,7 +836,7 @@ midori_app_set_property (GObject* object,
switch (prop_id) switch (prop_id)
{ {
case PROP_NAME: case PROP_NAME:
katze_assign (app->name, g_value_dup_string (value)); katze_assign (app_name, g_value_dup_string (value));
break; break;
case PROP_SETTINGS: case PROP_SETTINGS:
katze_object_assign (app->settings, g_value_dup_object (value)); katze_object_assign (app->settings, g_value_dup_object (value));
@ -873,7 +876,7 @@ midori_app_get_property (GObject* object,
switch (prop_id) switch (prop_id)
{ {
case PROP_NAME: case PROP_NAME:
g_value_set_string (value, app->name); g_value_set_string (value, app_name);
break; break;
case PROP_SETTINGS: case PROP_SETTINGS:
g_value_set_object (value, app->settings); g_value_set_object (value, app->settings);

View file

@ -41,6 +41,9 @@ midori_app_get_type (void) G_GNUC_CONST;
MidoriApp* MidoriApp*
midori_app_new (void); midori_app_new (void);
const gchar*
midori_app_get_name (MidoriApp* app);
gboolean gboolean
midori_app_instance_is_running (MidoriApp* app); midori_app_instance_is_running (MidoriApp* app);

View file

@ -32,6 +32,10 @@
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
#include <string.h> #include <string.h>
#ifdef HAVE_GRANITE
#include <granite.h>
#endif
#include <config.h> #include <config.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -247,6 +251,10 @@ static gboolean
_toggle_tabbar_smartly (MidoriBrowser* browser, _toggle_tabbar_smartly (MidoriBrowser* browser,
gboolean ignore_fullscreen) gboolean ignore_fullscreen)
{ {
#ifdef HAVE_GRANITE
gboolean has_tabs = !(midori_browser_is_fullscreen (browser) || ignore_fullscreen);
/* FIXME: Toggle tabbar visibility */
#else
gboolean has_tabs = gboolean has_tabs =
gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), 1) != NULL; gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), 1) != NULL;
gboolean show_tabs = 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_tabs (GTK_NOTEBOOK (browser->notebook), show_tabs);
gtk_notebook_set_show_border (GTK_NOTEBOOK (browser->notebook), show_tabs); gtk_notebook_set_show_border (GTK_NOTEBOOK (browser->notebook), show_tabs);
#endif
return has_tabs; return has_tabs;
} }
@ -293,7 +302,8 @@ _midori_browser_update_interface (MidoriBrowser* browser)
_action_set_sensitive (browser, "Next", _action_set_sensitive (browser, "Next",
midori_view_get_next_page (view) != NULL); 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, "SaveAs", midori_view_can_save (view));
_action_set_sensitive (browser, "Print", midori_view_can_print (view)); _action_set_sensitive (browser, "Print", midori_view_can_print (view));
_action_set_sensitive (browser, "ZoomIn", midori_view_can_zoom_in (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, _midori_browser_set_statusbar_text (MidoriBrowser* browser,
const gchar* text) 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)); GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
gboolean is_location = widget && GTK_IS_ENTRY (widget) gboolean is_location = widget && GTK_IS_ENTRY (widget)
&& GTK_IS_ALIGNMENT (gtk_widget_get_parent (widget)); && GTK_IS_ALIGNMENT (gtk_widget_get_parent (widget));
#endif
katze_assign (browser->statusbar_text, midori_uri_format_for_display (text)); 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"); GtkAction* action = _action_by_name (browser, "Location");
MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (action); 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_text (location_action, browser->statusbar_text); midori_location_action_set_secondary_icon (location_action, NULL);
midori_location_action_set_icon (location_action, NULL); #endif
midori_location_action_set_secondary_icon (location_action, NULL); }
} 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 else
{ midori_location_action_set_secondary_icon (
GtkWidget* view = midori_browser_get_current_tab (browser); location_action, GTK_STOCK_JUMP_TO);
if (G_LIKELY (view)) midori_location_action_set_text (location_action,
{ midori_view_get_display_uri (MIDORI_VIEW (view)));
if (g_object_get_data (G_OBJECT (view), "news-feeds")) midori_location_action_set_icon (location_action,
midori_location_action_set_secondary_icon ( midori_view_get_icon (MIDORI_VIEW (view)));
location_action, STOCK_NEWS_FEED); #endif
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)));
}
}
} }
else else
{ {
gtk_statusbar_pop (GTK_STATUSBAR (browser->statusbar), 1); gtk_statusbar_pop (GTK_STATUSBAR (browser->statusbar), 1);
gtk_statusbar_push (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")) if (katze_object_get_boolean (widget, "minimized"))
{ {
#ifdef HAVE_GRANITE
/* FIXME */
#else
GtkNotebook* notebook = GTK_NOTEBOOK (browser->notebook); GtkNotebook* notebook = GTK_NOTEBOOK (browser->notebook);
GtkWidget* label = gtk_notebook_get_tab_label (notebook, widget); GtkWidget* label = gtk_notebook_get_tab_label (notebook, widget);
gtk_widget_set_size_request (label, -1, -1); gtk_widget_set_size_request (label, -1, -1);
#endif
} }
else else
midori_browser_notebook_size_allocate_cb (NULL, NULL, browser); 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, midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
KatzeItem* bookmark, KatzeItem* bookmark,
gboolean new_bookmark, gboolean new_bookmark,
gboolean is_folder) gboolean is_folder,
GtkWidget* proxy)
{ {
const gchar* title; const gchar* title;
GtkWidget* dialog; GtkWidget* dialog;
@ -758,12 +784,23 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
title = new_bookmark ? _("New folder") : _("Edit folder"); title = new_bookmark ? _("New folder") : _("Edit folder");
else else
title = new_bookmark ? _("New bookmark") : _("Edit bookmark"); title = new_bookmark ? _("New bookmark") : _("Edit bookmark");
dialog = gtk_dialog_new_with_buttons ( #ifdef HAVE_GRANITE
title, GTK_WINDOW (browser), if (proxy != NULL)
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, {
/* 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, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
NULL);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_window_set_icon_name (GTK_WINDOW (dialog), gtk_window_set_icon_name (GTK_WINDOW (dialog),
new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE); new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
@ -1319,13 +1356,13 @@ midori_view_download_save_as_response_cb (GtkWidget* dialog,
static void static void
midori_browser_download_status_cb (WebKitDownload* download, midori_browser_download_status_cb (WebKitDownload* download,
GParamSpec* pspec, GParamSpec* pspec,
gpointer user_data) GtkWidget* widget)
{ {
const gchar* uri = webkit_download_get_destination_uri (download); const gchar* uri = webkit_download_get_destination_uri (download);
switch (webkit_download_get_status (download)) switch (webkit_download_get_status (download))
{ {
case WEBKIT_DOWNLOAD_STATUS_FINISHED: 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, sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Error opening the image!"), _("Error opening the image!"),
@ -1336,7 +1373,7 @@ midori_browser_download_status_cb (WebKitDownload* download,
webkit_download_cancel (download); webkit_download_cancel (download);
sokoke_message_dialog (GTK_MESSAGE_ERROR, sokoke_message_dialog (GTK_MESSAGE_ERROR,
_("Error downloading the image!"), _("Error downloading the image!"),
_("Can not downlaod selected image."), FALSE); _("Can not download selected image."), FALSE);
break; break;
case WEBKIT_DOWNLOAD_STATUS_CREATED: case WEBKIT_DOWNLOAD_STATUS_CREATED:
case WEBKIT_DOWNLOAD_STATUS_STARTED: case WEBKIT_DOWNLOAD_STATUS_STARTED:
@ -1380,7 +1417,7 @@ static gchar*
midori_browser_download_prepare_destination_uri (WebKitDownload* download, midori_browser_download_prepare_destination_uri (WebKitDownload* download,
const gchar* folder) const gchar* folder)
{ {
const gchar* suggested_filename; gchar* suggested_filename;
GFile* file_source; GFile* file_source;
gchar* file_basename; gchar* file_basename;
gchar* download_dir = NULL; gchar* download_dir = NULL;
@ -1388,8 +1425,9 @@ midori_browser_download_prepare_destination_uri (WebKitDownload* download,
gchar* destination_filename; gchar* destination_filename;
gchar* midori_tmp_dir; 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); file_source = g_file_new_for_uri (suggested_filename);
g_free (suggested_filename);
file_basename = g_file_get_basename (file_source); file_basename = g_file_get_basename (file_source);
if (folder == NULL) if (folder == NULL)
{ {
@ -1426,7 +1464,7 @@ midori_view_download_requested_cb (GtkWidget* view,
midori_browser_download_prepare_destination_uri (download, NULL); midori_browser_download_prepare_destination_uri (download, NULL);
midori_browser_prepare_download (browser, download, destination_uri); midori_browser_prepare_download (browser, download, destination_uri);
g_signal_connect (download, "notify::status", 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); webkit_download_start (download);
g_free (destination_uri); 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")) if (g_object_get_data (G_OBJECT (download), "save-as-download"))
{ {
static GtkWidget* dialog = NULL; static GtkWidget* dialog = NULL;
gchar* filename;
if (!dialog) if (!dialog)
{ {
@ -1453,8 +1492,9 @@ midori_view_download_requested_cb (GtkWidget* view,
G_CALLBACK (midori_view_download_save_as_response_cb), browser); G_CALLBACK (midori_view_download_save_as_response_cb), browser);
} }
g_object_set_data (G_OBJECT (dialog), "download", download); g_object_set_data (G_OBJECT (dialog), "download", download);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename = sokoke_get_download_filename (download);
webkit_download_get_suggested_filename (download)); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
g_free (filename);
gtk_widget_show (dialog); gtk_widget_show (dialog);
} }
else else
@ -1511,6 +1551,7 @@ midori_browser_tab_destroy_cb (GtkWidget* widget,
return FALSE; return FALSE;
} }
#ifndef HAVE_GRANITE
static void static void
midori_browser_notebook_resize (MidoriBrowser* browser, midori_browser_notebook_resize (MidoriBrowser* browser,
GdkRectangle* allocation) GdkRectangle* allocation)
@ -1554,33 +1595,33 @@ midori_browser_notebook_resize (MidoriBrowser* browser,
gtk_widget_set_size_request (label, new_size, -1); gtk_widget_set_size_request (label, new_size, -1);
} }
} }
#endif
static void static void
midori_browser_notebook_size_allocate_cb (GtkWidget* widget, midori_browser_notebook_size_allocate_cb (GtkWidget* widget,
GdkRectangle* allocation, GdkRectangle* allocation,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
#ifndef HAVE_GRANITE
if (!gtk_notebook_get_show_tabs (GTK_NOTEBOOK (browser->notebook))) if (!gtk_notebook_get_show_tabs (GTK_NOTEBOOK (browser->notebook)))
return; return;
midori_browser_notebook_resize (browser, allocation); midori_browser_notebook_resize (browser, allocation);
#endif
} }
static void static void
_midori_browser_add_tab (MidoriBrowser* browser, _midori_browser_add_tab (MidoriBrowser* browser,
GtkWidget* view) GtkWidget* view)
{ {
GtkNotebook* notebook = GTK_NOTEBOOK (browser->notebook); GtkWidget* notebook = browser->notebook;
#ifndef HAVE_GRANITE
GtkWidget* tab_label; GtkWidget* tab_label;
#endif
KatzeItem* item; KatzeItem* item;
guint n; guint n;
gtk_widget_set_can_focus (view, TRUE); 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)); item = midori_view_get_proxy_item (MIDORI_VIEW (view));
katze_array_add_item (browser->proxy_array, item); katze_array_add_item (browser->proxy_array, item);
@ -1613,7 +1654,7 @@ _midori_browser_add_tab (MidoriBrowser* browser,
midori_view_new_window_cb, browser, midori_view_new_window_cb, browser,
"signal::new-view", "signal::new-view",
midori_view_new_view_cb, browser, midori_view_new_view_cb, browser,
"signal::download-requested", "signal-after::download-requested",
midori_view_download_requested_cb, browser, midori_view_download_requested_cb, browser,
"signal::search-text", "signal::search-text",
midori_view_search_text_cb, browser, midori_view_search_text_cb, browser,
@ -1628,17 +1669,28 @@ _midori_browser_add_tab (MidoriBrowser* browser,
if (!katze_item_get_meta_boolean (item, "append") && if (!katze_item_get_meta_boolean (item, "append") &&
katze_object_get_boolean (browser->settings, "open-tabs-next-to-current")) 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); katze_array_move_item (browser->proxy_array, item, n);
} }
else else
n = -1; 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); 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 */ /* We want the tab to be removed if the widget is destroyed */
g_signal_connect (view, "destroy", g_signal_connect (view, "destroy",
G_CALLBACK (midori_browser_tab_destroy_cb), browser); 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))) && !webkit_web_view_can_paste_clipboard (WEBKIT_WEB_VIEW (focus)))
{ {
/* Space at the bottom of the page: Go to next page */ /* 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)); 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); GtkAdjustment* vadjust = gtk_scrolled_window_get_vadjustment (scrolled);
if (gtk_adjustment_get_value (vadjust) if (gtk_adjustment_get_value (vadjust)
== (gtk_adjustment_get_upper (vadjust) - gtk_adjustment_get_page_size (vadjust))) == (gtk_adjustment_get_upper (vadjust) - gtk_adjustment_get_page_size (vadjust)))
@ -2036,7 +2088,11 @@ midori_browser_class_init (MidoriBrowserClass* class)
"notebook", "notebook",
"Notebook", "Notebook",
"The notebook containing the views", "The notebook containing the views",
#ifdef HAVE_GRANITE
GRANITE_WIDGETS_TYPE_DYNAMIC_NOTEBOOK,
#else
GTK_TYPE_NOTEBOOK, GTK_TYPE_NOTEBOOK,
#endif
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, 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); GtkWidget* widget = midori_browser_get_current_tab (browser);
gboolean last_tab = 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 ()) if (last_tab && sokoke_is_app_or_private ())
{ {
gtk_widget_destroy (GTK_WIDGET (browser)); gtk_widget_destroy (GTK_WIDGET (browser));
@ -2699,14 +2755,14 @@ static void
_action_find_next_activate (GtkAction* action, _action_find_next_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
midori_findbar_find (MIDORI_FINDBAR (browser->find), TRUE); midori_findbar_find_text (MIDORI_FINDBAR (browser->find), NULL, TRUE);
} }
static void static void
_action_find_previous_activate (GtkAction* action, _action_find_previous_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
midori_findbar_find (MIDORI_FINDBAR (browser->find), FALSE); midori_findbar_find_text (MIDORI_FINDBAR (browser->find), NULL, FALSE);
} }
static void static void
@ -3026,9 +3082,9 @@ _action_window_activate_item_alt (GtkAction* action,
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
GtkWidget* view; 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) 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->bookmarkbar);
gtk_widget_hide (browser->navigationbar); gtk_widget_hide (browser->navigationbar);
gtk_widget_hide (browser->statusbar); 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_tabs (GTK_NOTEBOOK (browser->notebook), FALSE);
gtk_notebook_set_show_border (GTK_NOTEBOOK (browser->notebook), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (browser->notebook), FALSE);
#endif
gtk_window_fullscreen (GTK_WINDOW (browser)); gtk_window_fullscreen (GTK_WINDOW (browser));
} }
@ -3843,13 +3903,11 @@ _action_search_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
GSList* proxies = gtk_action_get_proxies (action); GSList* proxies = gtk_action_get_proxies (action);
guint i = 0;
GtkWidget* proxy;
const gchar* uri; const gchar* uri;
gchar* search; gchar* search;
while (((proxy = g_slist_nth_data (proxies, i++)))) for (; proxies != NULL; proxies = g_slist_next (proxies))
if (GTK_IS_TOOL_ITEM (proxy)) if (GTK_IS_TOOL_ITEM (proxies->data))
{ {
if (!gtk_widget_get_visible (browser->navigationbar)) if (!gtk_widget_get_visible (browser->navigationbar))
gtk_widget_show (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"); item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
if (KATZE_ITEM_IS_BOOKMARK (item)) 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 else
midori_browser_edit_bookmark_dialog_new (browser, item, FALSE, TRUE); midori_browser_edit_bookmark_dialog_new (browser, item, FALSE, TRUE, NULL);
} }
static void static void
@ -4106,10 +4164,19 @@ static void
_action_bookmark_add_activate (GtkAction* action, _action_bookmark_add_activate (GtkAction* action,
MidoriBrowser* browser) 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")) 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 else
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE); midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE, proxy);
} }
static void static void
@ -4551,19 +4618,34 @@ _action_inspect_page_activate (GtkAction* action,
webkit_web_inspector_show (inspector); 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 static void
_action_tab_move_backward_activate (GtkAction* action, _action_tab_move_backward_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
gint new_pos; gint new_pos;
gint cur_pos = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook)); gint cur_pos = midori_browser_get_current_page (browser);
GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), cur_pos); GtkWidget* widget = midori_browser_get_nth_tab (browser, cur_pos);
if (cur_pos > 0) if (cur_pos > 0)
new_pos = cur_pos - 1; new_pos = cur_pos - 1;
else 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); 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); g_signal_emit (browser, signals[MOVE_TAB], 0, browser->notebook, cur_pos, new_pos);
#endif
} }
static void static void
@ -4571,22 +4653,26 @@ _action_tab_move_forward_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
gint new_pos; gint new_pos;
gint cur_pos = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook)); gint cur_pos = midori_browser_get_current_page (browser);
GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), cur_pos); GtkWidget* widget = midori_browser_get_nth_tab (browser, cur_pos);
if (cur_pos == (gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)) - 1)) if (cur_pos == (midori_browser_get_n_pages (browser) - 1))
new_pos = 0; new_pos = 0;
else else
new_pos = cur_pos + 1; new_pos = cur_pos + 1;
#ifdef HAVE_GRANITE
/* FIXME */
#else
gtk_notebook_reorder_child (GTK_NOTEBOOK (browser->notebook), widget, new_pos); 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); g_signal_emit (browser, signals[MOVE_TAB], 0, browser->notebook, cur_pos, new_pos);
#endif
} }
static void static void
_action_tab_previous_activate (GtkAction* action, _action_tab_previous_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook)); gint n = midori_browser_get_current_page (browser);
gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n - 1); midori_browser_set_current_page (browser, n - 1);
} }
static void static void
@ -4594,10 +4680,10 @@ _action_tab_next_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
/* Advance one tab or jump to the first one if we are at the last one */ /* 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)); gint n = midori_browser_get_current_page (browser);
if (n == gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook)) - 1) if (n == midori_browser_get_n_pages (browser) - 1)
n = -1; n = -1;
gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n + 1); midori_browser_set_current_page (browser, n + 1);
} }
static void static void
@ -4729,7 +4815,7 @@ _action_help_link_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
const gchar* action_name; const gchar* action_name;
const gchar* uri; const gchar* uri = NULL;
gint n; gint n;
#if defined (G_OS_WIN32) && defined (DOCDIR) #if defined (G_OS_WIN32) && defined (DOCDIR)
gchar* free_uri = NULL; gchar* free_uri = NULL;
@ -4764,9 +4850,10 @@ _action_help_link_activate (GtkAction* action,
#endif #endif
} }
else if (!strncmp ("HelpBugs", action_name, 8)) else if (!strncmp ("HelpBugs", action_name, 8))
uri = PACKAGE_BUGREPORT; {
else if (!g_spawn_command_line_async ("ubuntu-bug " PACKAGE_NAME, NULL))
uri = NULL; uri = PACKAGE_BUGREPORT;
}
if (uri) if (uri)
{ {
@ -4950,6 +5037,20 @@ midori_browser_notebook_switch_page_after_cb (GtkWidget* notebook,
_midori_browser_update_progress (browser, view); _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 static void
midori_browser_notebook_page_reordered_cb (GtkNotebook* notebook, midori_browser_notebook_page_reordered_cb (GtkNotebook* notebook,
MidoriView* view, MidoriView* view,
@ -4961,6 +5062,15 @@ midori_browser_notebook_page_reordered_cb (GtkNotebook* notebook,
g_object_notify (G_OBJECT (browser), "tab"); 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 static gboolean
midori_browser_notebook_reorder_tab_cb (GtkNotebook* notebook, midori_browser_notebook_reorder_tab_cb (GtkNotebook* notebook,
GtkDirectionType arg1, GtkDirectionType arg1,
@ -5104,9 +5214,9 @@ static const GtkActionEntry entries[] =
NULL, G_CALLBACK (_action_add_speed_dial_activate) }, NULL, G_CALLBACK (_action_add_speed_dial_activate) },
{ "AddDesktopShortcut", NULL, { "AddDesktopShortcut", NULL,
#if HAVE_HILDON #if HAVE_HILDON
N_("Add Shortcut to the _desktop"), "<Ctrl>j", N_("Add Shortcut to the _desktop"), "",
#else #else
N_("Create _Launcher"), "<Ctrl>j", N_("Create _Launcher"), "",
#endif #endif
NULL, G_CALLBACK (_action_add_desktop_shortcut_activate) }, NULL, G_CALLBACK (_action_add_desktop_shortcut_activate) },
{ "AddNewsFeed", NULL, { "AddNewsFeed", NULL,
@ -5318,7 +5428,7 @@ static const GtkToggleActionEntry toggle_entries[] =
NULL, G_CALLBACK (_action_bookmarkbar_activate), NULL, G_CALLBACK (_action_bookmarkbar_activate),
FALSE }, FALSE },
{ "Statusbar", NULL, { "Statusbar", NULL,
N_("_Statusbar"), "", N_("_Statusbar"), "<Ctrl>j",
NULL, G_CALLBACK (_action_statusbar_activate), NULL, G_CALLBACK (_action_statusbar_activate),
FALSE }, 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. */ /* Switch to n-th tab. 9 and 0 go to the last tab. */
n = keyval - GDK_KEY_0; n = keyval - GDK_KEY_0;
browser = g_object_get_data (G_OBJECT (accel_group), "midori-browser"); browser = g_object_get_data (G_OBJECT (accel_group), "midori-browser");
if ((view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), if ((view = midori_browser_get_nth_tab (browser, n < 9 ? n - 1 : -1)))
n < 9 ? n - 1 : -1)))
midori_browser_set_current_tab (browser, view); midori_browser_set_current_tab (browser, view);
} }
} }
@ -6149,7 +6258,13 @@ midori_browser_init (MidoriBrowser* browser)
vpaned = gtk_vpaned_new (); vpaned = gtk_vpaned_new ();
gtk_paned_pack2 (GTK_PANED (hpaned), vpaned, TRUE, FALSE); gtk_paned_pack2 (GTK_PANED (hpaned), vpaned, TRUE, FALSE);
gtk_widget_show (vpaned); 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 (); browser->notebook = gtk_notebook_new ();
gtk_notebook_set_scrollable (GTK_NOTEBOOK (browser->notebook), TRUE);
#endif
#if !GTK_CHECK_VERSION (3, 0, 0) #if !GTK_CHECK_VERSION (3, 0, 0)
{ {
/* Remove the inner border between scrollbars and the window border */ /* Remove the inner border between scrollbars and the window border */
@ -6159,7 +6274,6 @@ midori_browser_init (MidoriBrowser* browser)
g_object_unref (rcstyle); g_object_unref (rcstyle);
} }
#endif #endif
gtk_notebook_set_scrollable (GTK_NOTEBOOK (browser->notebook), TRUE);
gtk_paned_pack1 (GTK_PANED (vpaned), browser->notebook, FALSE, FALSE); gtk_paned_pack1 (GTK_PANED (vpaned), browser->notebook, FALSE, FALSE);
g_signal_connect (browser->notebook, "switch-page", g_signal_connect (browser->notebook, "switch-page",
G_CALLBACK (midori_browser_notebook_switch_page_cb), 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_signal_connect_after (browser->notebook, "switch-page",
G_CALLBACK (midori_browser_notebook_switch_page_after_cb), G_CALLBACK (midori_browser_notebook_switch_page_after_cb),
browser); 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_signal_connect (browser->notebook, "page-reordered",
G_CALLBACK (midori_browser_notebook_page_reordered_cb), G_CALLBACK (midori_browser_notebook_page_reordered_cb),
browser); 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_signal_connect (browser->notebook, "size-allocate",
G_CALLBACK (midori_browser_notebook_size_allocate_cb), G_CALLBACK (midori_browser_notebook_size_allocate_cb),
browser); browser);
@ -6317,6 +6439,97 @@ _midori_browser_set_toolbar_style (MidoriBrowser* browser,
gtk_toolbar_style); 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 static gboolean
midori_browser_toolbar_item_button_press_event_cb (GtkWidget* toolitem, midori_browser_toolbar_item_button_press_event_cb (GtkWidget* toolitem,
GdkEventButton* event, GdkEventButton* event,
@ -6336,11 +6549,29 @@ midori_browser_toolbar_item_button_press_event_cb (GtkWidget* toolitem,
} }
else if (MIDORI_EVENT_CONTEXT_MENU (event)) else if (MIDORI_EVENT_CONTEXT_MENU (event))
{ {
midori_browser_toolbar_popup_context_menu_cb ( if (g_object_get_data (G_OBJECT (toolitem), "history-back"))
GTK_IS_BIN (toolitem) && gtk_bin_get_child (GTK_BIN (toolitem)) ? {
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, 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 TRUE;
} }
return FALSE; return FALSE;
@ -6430,14 +6661,28 @@ _midori_browser_set_toolbar_items (MidoriBrowser* browser,
} }
else if (token_current != token_dontcare && token_last == token_dontcare) else if (token_current != token_dontcare && token_last == token_dontcare)
continue; 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 else
toolitem = gtk_action_create_tool_item (action); toolitem = gtk_action_create_tool_item (action);
if (gtk_bin_get_child (GTK_BIN (toolitem))) 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)), g_signal_connect (gtk_bin_get_child (GTK_BIN (toolitem)),
"button-press-event", "button-press-event",
G_CALLBACK (midori_browser_toolbar_item_button_press_event_cb), G_CALLBACK (midori_browser_toolbar_item_button_press_event_cb),
browser); browser);
}
else else
{ {
gtk_tool_item_set_use_drag_window (GTK_TOOL_ITEM (toolitem), TRUE); 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_critical ("midori_load_soup_session was not called!");
g_signal_emit (browser, signals[ADD_TAB], 0, view); 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: * midori_browser_remove_tab:
* @browser: a #MidoriBrowser * @browser: a #MidoriBrowser
@ -7275,10 +7549,15 @@ midori_browser_set_current_page (MidoriBrowser* browser,
g_return_if_fail (MIDORI_IS_BROWSER (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); 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); gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
#endif
if (midori_view_is_blank (MIDORI_VIEW (view))) if (midori_view_is_blank (MIDORI_VIEW (view)))
midori_browser_activate_action (browser, "Location"); midori_browser_activate_action (browser, "Location");
else else
@ -7305,7 +7584,12 @@ midori_browser_get_current_page (MidoriBrowser* browser)
{ {
g_return_val_if_fail (MIDORI_IS_BROWSER (browser), -1); 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)); return gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
#endif
} }
/** /**
@ -7325,9 +7609,19 @@ GtkWidget*
midori_browser_get_nth_tab (MidoriBrowser* browser, midori_browser_get_nth_tab (MidoriBrowser* browser,
gint page) 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); g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
return gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), page); 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 (MIDORI_IS_BROWSER (browser));
g_return_if_fail (GTK_IS_WIDGET (view)); 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); 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); 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) if (n >= 0)
return gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n); return midori_browser_get_nth_tab (browser, n);
else else
return NULL; return NULL;
} }

View file

@ -152,6 +152,10 @@ GtkWidget*
midori_browser_get_current_tab (MidoriBrowser* browser); midori_browser_get_current_tab (MidoriBrowser* browser);
#define midori_browser_get_tab midori_browser_get_current_tab #define midori_browser_get_tab midori_browser_get_current_tab
gint
midori_browser_page_num (MidoriBrowser* browser,
GtkWidget* view);
GList* GList*
midori_browser_get_tabs (MidoriBrowser* browser); midori_browser_get_tabs (MidoriBrowser* browser);

View file

@ -25,6 +25,7 @@ struct _MidoriExtensionPrivate
gchar* version; gchar* version;
gchar* authors; gchar* authors;
gchar* website; gchar* website;
gchar* key;
MidoriApp* app; MidoriApp* app;
gint active; gint active;
@ -127,7 +128,8 @@ enum
PROP_DESCRIPTION, PROP_DESCRIPTION,
PROP_VERSION, PROP_VERSION,
PROP_AUTHORS, PROP_AUTHORS,
PROP_WEBSITE PROP_WEBSITE,
PROP_KEY
}; };
enum { enum {
@ -260,6 +262,23 @@ midori_extension_class_init (MidoriExtensionClass* class)
NULL, NULL,
flags)); 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)); 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->version, NULL);
katze_assign (extension->priv->authors, NULL); katze_assign (extension->priv->authors, NULL);
katze_assign (extension->priv->website, NULL); katze_assign (extension->priv->website, NULL);
katze_assign (extension->priv->key, NULL);
katze_assign (extension->priv->config_dir, NULL); katze_assign (extension->priv->config_dir, NULL);
g_list_free (extension->priv->lsettings); g_list_free (extension->priv->lsettings);
@ -446,6 +466,9 @@ midori_extension_set_property (GObject* object,
case PROP_WEBSITE: case PROP_WEBSITE:
katze_assign (extension->priv->website, g_value_dup_string (value)); katze_assign (extension->priv->website, g_value_dup_string (value));
break; break;
case PROP_KEY:
katze_assign (extension->priv->key, g_value_dup_string (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -477,6 +500,9 @@ midori_extension_get_property (GObject* object,
case PROP_WEBSITE: case PROP_WEBSITE:
g_value_set_string (value, extension->priv->website); g_value_set_string (value, extension->priv->website);
break; break;
case PROP_KEY:
g_value_set_string (value, extension->priv->key);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;

View file

@ -369,6 +369,77 @@ midori_location_action_popup_position (MidoriLocationAction* action,
gtk_window_move (GTK_WINDOW (popup), wx, wy); 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 static gboolean
midori_location_action_treeview_button_press_cb (GtkWidget* treeview, midori_location_action_treeview_button_press_cb (GtkWidget* treeview,
GdkEventButton* event, 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_model_get_iter (action->completion_model, &iter, path);
gtk_tree_path_free (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_tree_model_get (action->completion_model, &iter, URI_COL, &uri, -1);
gtk_entry_set_text (GTK_ENTRY (action->entry), uri); midori_location_action_complete (action,
g_signal_emit (action, signals[SUBMIT_URI], 0, uri, MIDORI_MOD_NEW_TAB (event->state), uri);
MIDORI_MOD_NEW_TAB (event->state));
g_free (uri); g_free (uri);
return TRUE; return TRUE;
@ -411,7 +478,6 @@ midori_location_action_popup_timeout_cb (gpointer data)
static sqlite3_stmt* stmt; static sqlite3_stmt* stmt;
const gchar* sqlcmd; const gchar* sqlcmd;
gint matches, searches; gint matches, searches;
GtkStyle* style;
if (!action->entry || !gtk_widget_has_focus (action->entry) || !action->history) if (!action->entry || !gtk_widget_has_focus (action->entry) || !action->history)
return FALSE; return FALSE;
@ -519,6 +585,8 @@ midori_location_action_popup_timeout_cb (gpointer data)
renderer = gtk_cell_renderer_text_new (); renderer = gtk_cell_renderer_text_new ();
g_object_set_data (G_OBJECT (renderer), "location-action", action); g_object_set_data (G_OBJECT (renderer), "location-action", action);
gtk_cell_renderer_set_fixed_size (renderer, 1, -1); 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_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer, gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer,
"cell-background-gdk", BACKGROUND_COL, "cell-background-gdk", BACKGROUND_COL,
@ -537,8 +605,6 @@ midori_location_action_popup_timeout_cb (gpointer data)
gtk_list_store_clear (store); gtk_list_store_clear (store);
matches = searches = 0; matches = searches = 0;
gtk_widget_realize (action->treeview);
style = gtk_widget_get_style (action->treeview);
while (result == SQLITE_ROW) while (result == SQLITE_ROW)
{ {
sqlite3_int64 type = sqlite3_column_int64 (stmt, 0); sqlite3_int64 type = sqlite3_column_int64 (stmt, 0);
@ -577,35 +643,7 @@ midori_location_action_popup_timeout_cb (gpointer data)
} }
if (action->search_engines) if (action->search_engines)
{ searches += midori_location_action_add_search_engines (action, store, matches);
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;
}
if (!gtk_widget_get_visible (action->popup)) 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; GtkTreeModel* model = location_action->completion_model;
GtkTreeIter iter; GtkTreeIter iter;
gint selected = location_action->completion_index; gint selected = location_action->completion_index;
midori_location_action_popdown_completion (location_action);
if (selected > -1 && if (selected > -1 &&
gtk_tree_model_iter_nth_child (model, &iter, NULL, selected)) gtk_tree_model_iter_nth_child (model, &iter, NULL, selected))
{ {
gchar* uri; gchar* uri;
gtk_tree_model_get (model, &iter, URI_COL, &uri, -1); gtk_tree_model_get (model, &iter, URI_COL, &uri, -1);
gtk_entry_set_text (entry, uri);
if (is_enter) if (is_enter)
g_signal_emit (action, signals[SUBMIT_URI], 0, uri, midori_location_action_complete (location_action,
MIDORI_MOD_NEW_TAB (event->state)); MIDORI_MOD_NEW_TAB (event->state), uri);
else
{
midori_location_action_popdown_completion (location_action);
gtk_entry_set_text (entry, uri);
}
g_free (uri); g_free (uri);
return TRUE; return TRUE;
} }
midori_location_action_popdown_completion (location_action);
} }
if (is_enter) if (is_enter && (text = gtk_entry_get_text (entry)) && *text)
if ((text = gtk_entry_get_text (entry)) && *text) g_signal_emit (action, signals[SUBMIT_URI], 0, text,
g_signal_emit (action, signals[SUBMIT_URI], 0, text, MIDORI_MOD_NEW_TAB (event->state));
MIDORI_MOD_NEW_TAB (event->state));
break; break;
case GDK_KEY_Escape: case GDK_KEY_Escape:
{ {

View file

@ -429,11 +429,13 @@ midori_preferences_set_settings (MidoriPreferences* preferences,
button = katze_property_proxy (settings, "open-new-pages-in", NULL); button = katze_property_proxy (settings, "open-new-pages-in", NULL);
SPANNED_ADD (button); SPANNED_ADD (button);
#if !HAVE_HILDON #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); 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); SPANNED_ADD (button);
#endif #endif
#endif
button = katze_property_proxy (settings, "open-tabs-next-to-current", NULL); button = katze_property_proxy (settings, "open-tabs-next-to-current", NULL);
INDENTED_ADD (button); INDENTED_ADD (button);
button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL); button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);

View file

@ -13,11 +13,17 @@
#include "midori-view.h" #include "midori-view.h"
#include "midori-browser.h" #include "midori-browser.h"
#include "midori-searchaction.h" #include "midori-searchaction.h"
#include "midori-app.h"
#include "midori-platform.h" #include "midori-platform.h"
#include "midori-core.h" #include "midori-core.h"
#include "midori-findbar.h"
#include "marshal.h" #include "marshal.h"
#ifdef HAVE_GRANITE
#include <granite.h>
#endif
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
@ -108,6 +114,12 @@ struct _MidoriView
gboolean back_forward_set; gboolean back_forward_set;
GHashTable* memory; GHashTable* memory;
GtkWidget* scrolled_window; GtkWidget* scrolled_window;
#if GTK_CHECK_VERSION (3, 2, 0)
GtkWidget* overlay;
GtkWidget* overlay_label;
GtkWidget* overlay_find;
#endif
}; };
struct _MidoriViewClass struct _MidoriViewClass
@ -595,10 +607,29 @@ midori_view_class_init (MidoriViewClass* class)
flags)); 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 static void
midori_view_set_title (MidoriView* view, const gchar* title) midori_view_set_title (MidoriView* view, const gchar* title)
{ {
const gchar* display_title; const gchar* display_title;
#ifdef HAVE_GRANITE
GraniteWidgetsTab* tab;
#endif
if (!title) if (!title)
title = view->uri; title = view->uri;
@ -632,6 +663,12 @@ midori_view_set_title (MidoriView* view, const gchar* title)
#endif #endif
display_title = midori_view_get_display_title (view); 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 (view->tab_label)
{ {
/* If the title starts with the presumed name of the website, we /* If the title starts with the presumed name of the website, we
@ -667,6 +704,11 @@ midori_view_apply_icon (MidoriView* view,
GdkPixbuf* icon, GdkPixbuf* icon,
const gchar* icon_name) 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_set_icon (view->item, icon_name);
/* katze_item_get_image knows about this pixbuf */ /* katze_item_get_image knows about this pixbuf */
g_object_set_data_full (G_OBJECT (view->item), "pixbuf", g_object_ref (icon), 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; view->load_status = load_status;
g_object_notify (G_OBJECT (view), "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) if (view->tab_icon)
katze_throbber_set_animated (KATZE_THROBBER (view->tab_icon), katze_throbber_set_animated (KATZE_THROBBER (view->tab_icon),
view->load_status != MIDORI_LOAD_FINISHED); 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); 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, 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; " "{ var t = l[i].type; var r = l[i].rel; "
"if (t && (t.indexOf ('rss') != -1 || t.indexOf ('atom') != -1)) " "if (t && (t.indexOf ('rss') != -1 || t.indexOf ('atom') != -1)) "
"f.push ('$' + l[i].href + '|' + l[i].title);" "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) #if !WEBKIT_CHECK_VERSION (1, 1, 18)
"else if (r && r.indexOf ('icon') != -1) f.push (l[i].href); " "else if (r && r.indexOf ('icon') != -1) f.push (l[i].href); "
#endif #endif
"} return f; })(" "} return f; })("
"document.getElementsByTagName ('link'));", NULL); "document.getElementsByTagName ('link'));", NULL);
/* FIXME: If URI or title contains , parsing will break */
gchar** items = g_strsplit (value, ",", 0); gchar** items = g_strsplit (value, ",", 0);
gchar** current_item = items; gchar** current_item = items;
gchar* default_uri = NULL; gchar* default_uri = NULL;
@ -1511,7 +1560,7 @@ webkit_web_view_load_finished_cb (WebKitWebView* web_view,
continue; continue;
title = strchr (uri_and_title, '|'); title = strchr (uri_and_title, '|');
if (title == NULL) if (title == NULL)
continue; goto news_feeds_continue;
title++; title++;
uri = g_strndup (uri_and_title, title - 1 - uri_and_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 else
g_free (uri); 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) #if !WEBKIT_CHECK_VERSION (1, 1, 18)
else else
katze_assign (view->icon_uri, g_strdup (uri_and_title)); katze_assign (view->icon_uri, g_strdup (uri_and_title));
#endif #endif
news_feeds_continue:
current_item++; current_item++;
} }
g_strfreev (items); g_strfreev (items);
@ -1716,12 +1782,7 @@ midori_view_web_view_button_press_event_cb (WebKitWebView* web_view,
view->button_press_handled = TRUE; view->button_press_handled = TRUE;
return TRUE; return TRUE;
} }
else if (MIDORI_MOD_SCROLL (event->state)) if (view->middle_click_opens_selection)
{
midori_view_set_zoom_level (MIDORI_VIEW (view), 1.0);
return FALSE; /* Allow Ctrl + Middle click */
}
else if (view->middle_click_opens_selection)
{ {
gboolean is_editable; gboolean is_editable;
WebKitHitTestResult* result; WebKitHitTestResult* result;
@ -1731,56 +1792,63 @@ midori_view_web_view_button_press_event_cb (WebKitWebView* web_view,
context = katze_object_get_int (result, "context"); context = katze_object_get_int (result, "context");
is_editable = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE; is_editable = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
g_object_unref (result); g_object_unref (result);
if (is_editable) 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)))
{ {
guint i = 0; clipboard = gtk_clipboard_get_for_display (
while (uri[i++] != '\0') gtk_widget_get_display (GTK_WIDGET (view)),
if (uri[i] == '\n' || uri[i] == '\r') GDK_SELECTION_PRIMARY);
uri[i] = ' '; if ((uri = gtk_clipboard_wait_for_text (clipboard)))
g_strstrip (uri);
/* Hold Alt to search for the selected word */
if (event->state & GDK_MOD1_MASK)
{ {
new_uri = sokoke_magic_uri (uri); guint i = 0;
if (!new_uri) 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 ( new_uri = sokoke_magic_uri (uri);
view->settings, "location-entry-search"); if (!new_uri)
new_uri = midori_uri_for_search (search, uri); {
g_free (search); 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; break;
case 3: case 3:
if (event->state & GDK_CONTROL_MASK) 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;" " border:1px solid gray; padding:0 0.1em 0.2em 0.1em !important;"
" position:absolute; display:inline !important; }');" " position:absolute; display:inline !important; }');"
" var label_count = 0;" " var label_count = 0;"
" for (i in document.links) {" " for (var i in document.links) {"
" if (document.links[i].href && document.links[i].insertBefore) {" " if (document.links[i].href && document.links[i].insertBefore) {"
" var child = document.createElement ('span');" " var child = document.createElement ('span');"
" if (document.links[i].accessKey && isNaN (document.links[i].accessKey)) {" " 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)) && !webkit_web_view_can_paste_clipboard (web_view))
{ {
gchar* text = character ? g_strdup_printf ("%c", character) : NULL; 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 : ""); g_signal_emit (view, signals[SEARCH_TEXT], 0, TRUE, text ? text : "");
#endif
g_free (text); g_free (text);
return TRUE; return TRUE;
} }
@ -2286,7 +2359,8 @@ midori_view_populate_popup (MidoriView* view,
context = katze_object_get_int (view->hit_test, "context"); context = katze_object_get_int (view->hit_test, "context");
has_selection = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION; has_selection = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;
/* Ensure view->selected_text */ /* 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_editable = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
is_image = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE; is_image = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;
is_media = context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA; 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, midori_view_insert_menu_item (menu_shell, 0,
_("_Search the Web"), GTK_STOCK_FIND, _("_Search the Web"), GTK_STOCK_FIND,
G_CALLBACK (midori_web_view_menu_search_web_activate_cb), widget); G_CALLBACK (midori_web_view_menu_search_web_activate_cb), widget);
/* FIXME: choose 3 most frequently */
g_strstrip (view->selected_text); g_strstrip (view->selected_text);
if (midori_uri_is_valid (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, webkit_web_view_web_view_ready_cb (GtkWidget* web_view,
MidoriView* view) MidoriView* view)
{ {
GtkWidget* new_view = gtk_widget_get_parent (gtk_widget_get_parent (web_view));
MidoriNewView where = MIDORI_NEW_VIEW_TAB; 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 /* FIXME: Open windows opened by scripts in tabs if they otherwise
would be replacing the page the user opened. */ 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* content_type;
gchar* description; gchar* description;
gchar* file_type; gchar* file_type;
gchar* name;
gchar* file_name; gchar* file_name;
WebKitDownload *download; WebKitDownload *download;
WebKitWebDataSource* datasource; WebKitWebDataSource* datasource;
@ -2786,9 +2862,6 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
GtkIconTheme* icon_theme; GtkIconTheme* icon_theme;
gint response; 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)) if (webkit_web_view_can_show_mime_type (WEBKIT_WEB_VIEW (web_view), mime_type))
{ {
gboolean view_source = FALSE; gboolean view_source = FALSE;
@ -2836,8 +2909,9 @@ webkit_web_view_mime_type_decision_cb (GtkWidget* web_view,
g_free (description); g_free (description);
download = webkit_download_new (request); download = webkit_download_new (request);
file_name = g_strdup_printf (_("File Name: %s"), name = sokoke_get_download_filename (download);
webkit_download_get_suggested_filename (download)); file_name = g_strdup_printf (_("File Name: %s"), name);
g_free (name);
g_object_unref (download); g_object_unref (download);
/* Link Fingerprint */ /* 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); g_object_set_data (G_OBJECT (view), "open-download", (gpointer)0);
switch (response) switch (response)
{ {
case 4: case 4:
g_object_set_data (G_OBJECT (view), "save-as-download", (gpointer)1); g_object_set_data (G_OBJECT (view), "save-as-download", (gpointer)1);
webkit_web_policy_decision_download (decision); webkit_web_policy_decision_download (decision);
webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (view->web_view)); break;
return TRUE;
case 3: case 3:
g_object_set_data (G_OBJECT (view), "open-download", (gpointer)1); g_object_set_data (G_OBJECT (view), "open-download", (gpointer)1);
case 1: case 1:
webkit_web_policy_decision_download (decision); webkit_web_policy_decision_download (decision);
/* Apparently WebKit will continue loading which ends in an error. break;
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;
case 2: case 2:
case GTK_RESPONSE_DELETE_EVENT:
webkit_web_policy_decision_ignore (decision);
break;
default: default:
/* Apparently WebKit will continue loading which ends in an error. g_warn_if_reached ();
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;
} }
/* 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 static gboolean
@ -3106,7 +3181,27 @@ midori_view_init (MidoriView* view)
view->scrolled_window = katze_scrolled_new (NULL, NULL); view->scrolled_window = katze_scrolled_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view->scrolled_window), gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view->scrolled_window),
GTK_SHADOW_NONE); 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); gtk_box_pack_start (GTK_BOX (view), view->scrolled_window, TRUE, TRUE, 0);
#endif
g_signal_connect (view->item, "meta-data-changed", g_signal_connect (view->item, "meta-data-changed",
G_CALLBACK (midori_view_item_meta_data_changed), view); G_CALLBACK (midori_view_item_meta_data_changed), view);
@ -3696,22 +3791,22 @@ midori_view_construct_web_view (MidoriView* view)
NULL); NULL);
} }
static gchar* list_netscape_plugins () static void
list_netscape_plugins (GString* ns_plugins,
JSContextRef js_context)
{ {
if (midori_web_settings_has_plugin_support ()) if (!midori_web_settings_has_plugin_support ())
{ return;
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);
/* Joins available plugins like this: URI1|title1,URI2|title2 */ /* Joins available plugins like this: URI1|title1,URI2|title2 */
gchar* value = sokoke_js_script_eval (js_context, 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; " "{ var p = l[i].name + '|' + l[i].filename; "
"if (f.indexOf (p) == -1) f.push (p); } return f; }" "if (f.indexOf (p) == -1) f.push (p); } return f; }"
"plugins (navigator.plugins)", NULL); "plugins (navigator.plugins)", NULL);
gchar** items = g_strsplit (value, ",", 0); gchar** items = g_strsplit (value, ",", 0);
guint i = 0; guint i = 0;
GString* ns_plugins = g_string_new ("<h2>Netscape Plugins:</h2><table>"); g_string_append (ns_plugins, "<h2>Netscape Plugins:</h2><table>");
if (items != NULL) if (items != NULL)
while (items[i] != NULL) while (items[i] != NULL)
{ {
@ -3732,19 +3827,48 @@ static gchar* list_netscape_plugins ()
g_string_append (ns_plugins, "</table>"); g_string_append (ns_plugins, "</table>");
g_strfreev (items); g_strfreev (items);
g_free (value); g_free (value);
gtk_widget_destroy (web_view); }
return g_string_free (ns_plugins, FALSE);
} static void
else list_geolocation (GString* markup)
return g_strdup (""); {
g_string_append (markup,
"<a href=\"http://dev.w3.org/geo/api/spec-source.html\" id=\"method\"></a>"
"<span id=\"locationInfo\"><noscript>No Geolocation without Javascript</noscript></span>"
"<script>"
"function displayLocation (position) {"
"var geouri = 'geo:' + position.coords.latitude + ',' + position.coords.longitude + ',' + position.coords.altitude + ',u=' + position.coords.accuracy;"
"document.getElementById('locationInfo').innerHTML = '<a href=\"' + geouri + '\">' + geouri + '</a><br><code>'"
"+ ' timestamp: ' + position.timestamp"
"+ ' latitude: ' + position.coords.latitude"
"+ ' longitude: ' + position.coords.longitude"
"+ ' altitude: ' + position.coords.altitude + '<br>'"
"+ ' accuracy: ' + position.coords.accuracy"
"+ ' altitudeAccuracy: ' + position.coords.altitudeAccuracy"
"+ ' heading: ' + position.coords.heading"
"+ ' speed: ' + position.coords.speed"
"+ '</code>'; }"
"function handleError (error) {"
"var errorMessage = '<b>' + ['Unknown error', 'Permission denied', 'Position failed', 'Timed out'][error.code] + '</b>';"
"if (error.code == 3) document.getElementById('locationInfo').innerHTML += (' ' + errorMessage);"
"else document.getElementById('locationInfo').innerHTML = errorMessage; }"
"if (navigator.geolocation) {"
"var options = { enableHighAccuracy: true, timeout: 60000, maximumAge: \"Infinite\" };"
" if (navigator.geolocation.watchPosition) {"
" document.getElementById('method').innerHTML = '<code>geolocation.watchPosition</code>:';"
" navigator.geolocation.watchPosition(displayLocation, handleError, options);"
" } else {"
" document.getElementById('method').innerHTML = '<code>geolocation.getCurrentPosition</code>:';"
" navigator.geolocation.getCurrentPosition(displayLocation, handleError);"
" }"
"} else"
" document.getElementById('locationInfo').innerHTML = 'Geolocation unavailable';"
"</script>");
} }
static gchar* 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, gchar* value = sokoke_js_script_eval (js_context,
"var supported = function (format) { " "var supported = function (format) { "
"var video = document.createElement('video');" "var video = document.createElement('video');"
@ -3757,10 +3881,27 @@ list_video_formats ()
"' &nbsp; WebM [' + " "' &nbsp; WebM [' + "
"supported('video/webm; codecs=\"vp8, vorbis\"') + ']' " "supported('video/webm; codecs=\"vp8, vorbis\"') + ']' "
"", NULL); "", NULL);
gtk_widget_destroy (web_view);
return value; 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, "<p>");
guint i;
for (i = 0; i < G_N_ELEMENTS (valid_about_uris); i++)
g_string_append_printf (markup, "<a href=\"%s\">%s</a> &nbsp;",
valid_about_uris[i], valid_about_uris[i]);
}
static gchar* static gchar*
prepare_speed_dial_html (MidoriView* view, prepare_speed_dial_html (MidoriView* view,
gboolean load_missing) gboolean load_missing)
@ -4033,6 +4174,13 @@ midori_view_set_uri (MidoriView* view,
_("The language and timezone are not revealed to websites."), _("The language and timezone are not revealed to websites."),
_("Flash and other Netscape plugins cannot be listed by 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")) else if (!strcmp (uri, "about:") || !strcmp (uri, "about:version"))
{ {
gchar* arguments = g_strjoinv (" ", sokoke_get_argv (NULL)); 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 ( const gchar* sys_name = midori_web_settings_get_system_name (
&architecture, &platform); &architecture, &platform);
gchar* ident = katze_object_get_string (view->settings, "user-agent"); gchar* ident = katze_object_get_string (view->settings, "user-agent");
gchar* netscape_plugins = list_netscape_plugins (); WebKitWebFrame* web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (view->web_view));
gchar* video_formats = list_video_formats (); 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)); katze_assign (view->uri, g_strdup (uri));
data = g_strdup_printf ( data = g_strdup_printf (
@ -4054,12 +4206,13 @@ midori_view_set_uri (MidoriView* view,
"style=\"position: absolute; right: 15px; bottom: 15px; z-index: -9;\">" "style=\"position: absolute; right: 15px; bottom: 15px; z-index: -9;\">"
"<table>" "<table>"
"<tr><td>Command&nbsp;line</td><td>%s</td></tr>" "<tr><td>Command&nbsp;line</td><td>%s</td></tr>"
"<tr><td>Midori</td><td>%s</td></tr>" "<tr><td>Midori</td><td>%s (%s)</td></tr>"
"<tr><td>WebKitGTK+</td><td>%d.%d.%d (%d.%d.%d)</td></tr>" "<tr><td>WebKitGTK+</td><td>%d.%d.%d (%d.%d.%d)</td></tr>"
"<tr><td>GTK+</td><td>%d.%d.%d (%d.%d.%d)</td></tr>" "<tr><td>GTK+</td><td>%d.%d.%d (%d.%d.%d)</td></tr>"
"<tr><td>Glib</td><td>%d.%d.%d (%d.%d.%d)</td></tr>" "<tr><td>Glib</td><td>%d.%d.%d (%d.%d.%d)</td></tr>"
"<tr><td>libsoup</td><td>%s</td></tr>" "<tr><td>libsoup</td><td>%s</td></tr>"
"<tr><td>cairo</td><td>%s (%s)</td></tr>" "<tr><td>cairo</td><td>%s (%s)</td></tr>"
"<tr><td>granite</td><td>%s</td></tr>"
"<tr><td>libnotify</td><td>%s</td></tr>" "<tr><td>libnotify</td><td>%s</td></tr>"
"<tr><td>single instance</td><td>%s</td></tr>" "<tr><td>single instance</td><td>%s</td></tr>"
"<tr><td>Platform</td><td>%s %s %s</td></tr>" "<tr><td>Platform</td><td>%s %s %s</td></tr>"
@ -4070,7 +4223,7 @@ midori_view_set_uri (MidoriView* view,
"</body></html>", "</body></html>",
_("Version numbers in brackets show the version used at runtime."), _("Version numbers in brackets show the version used at runtime."),
command_line, command_line,
PACKAGE_VERSION, PACKAGE_VERSION, midori_app_get_name (NULL),
WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION, WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, WEBKIT_MICRO_VERSION,
webkit_major_version (), webkit_major_version (),
webkit_minor_version (), webkit_minor_version (),
@ -4081,6 +4234,7 @@ midori_view_set_uri (MidoriView* view,
glib_major_version, glib_minor_version, glib_micro_version, glib_major_version, glib_minor_version, glib_micro_version,
LIBSOUP_VERSION, LIBSOUP_VERSION,
CAIRO_VERSION_STRING, cairo_version_string (), CAIRO_VERSION_STRING, cairo_version_string (),
GRANITE_VERSION,
LIBNOTIFY_VERSION, LIBNOTIFY_VERSION,
#ifdef HAVE_HILDON_2_2 #ifdef HAVE_HILDON_2_2
"Hildon 2.2", "Hildon 2.2",
@ -4092,12 +4246,12 @@ midori_view_set_uri (MidoriView* view,
"Sockets", "Sockets",
#endif #endif
platform, sys_name, architecture ? architecture : "", ident, platform, sys_name, architecture ? architecture : "", ident,
video_formats, netscape_plugins); video_formats, (gchar*)(more->str));
g_free (command_line); g_free (command_line);
g_free (arguments); g_free (arguments);
g_free (ident); g_free (ident);
g_free (netscape_plugins);
g_free (video_formats); g_free (video_formats);
g_string_free (more, TRUE);
} }
else else
{ {
@ -4159,6 +4313,33 @@ midori_view_set_uri (MidoriView* view,
} }
} }
/**
* midori_view_set_overlay_text:
* @view: a #MidoriView
* @text: a URI or text string
*
* Show a specified URI or text on top of the view.
* Has no effect with < GTK+ 3.2.0.
*
* Since: 0.4.5
**/
void
midori_view_set_overlay_text (MidoriView* view,
const gchar* text)
{
g_return_if_fail (MIDORI_IS_VIEW (view));
#if GTK_CHECK_VERSION (3, 2, 0)
if (text == NULL)
gtk_widget_hide (view->overlay_label);
else
{
gtk_label_set_text (GTK_LABEL (view->overlay_label), text);
gtk_widget_show (view->overlay_label);
}
#endif
}
/** /**
* midori_view_is_blank: * midori_view_is_blank:
* @view: a #MidoriView * @view: a #MidoriView
@ -5057,7 +5238,6 @@ midori_view_get_uri_extension (const gchar* uri)
while (*ext_end && g_ascii_isalnum (*ext_end)) while (*ext_end && g_ascii_isalnum (*ext_end))
ext_end++; ext_end++;
*ext_end = 0;
return g_strdup (period); return g_strdup (period);
} }
@ -5129,12 +5309,13 @@ midori_view_save_source (MidoriView* view,
{ {
if ((fp = fdopen (fd, "w"))) if ((fp = fdopen (fd, "w")))
{ {
ret = fwrite (data->str, 1, data->len, fp); ret = fwrite (data ? data->str : "", 1, data ? data->len : 0, fp);
fclose (fp); fclose (fp);
if ((ret - data->len) != 0) if (ret - (data ? data->len : 0) != 0)
{ {
g_warning ("Error writing to file %s " midori_view_add_info_bar (view, GTK_MESSAGE_ERROR,
"in midori_browser_source_transfer_cb()", unique_filename); unique_filename, NULL, view,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
katze_assign (unique_filename, NULL); katze_assign (unique_filename, NULL);
} }
} }
@ -5261,6 +5442,48 @@ midori_view_go_forward (MidoriView* view)
webkit_web_view_go_forward (WEBKIT_WEB_VIEW (view->web_view)); webkit_web_view_go_forward (WEBKIT_WEB_VIEW (view->web_view));
} }
/**
* midori_view_go_back_or_forward
* @view: a #MidoriView
* @steps: number of steps to jump in history
*
* Goes back or forward in history.
*
* Since: 0.4.5
**/
void
midori_view_go_back_or_forward (MidoriView* view,
gint steps)
{
g_return_if_fail (MIDORI_IS_VIEW (view));
webkit_web_view_go_back_or_forward (WEBKIT_WEB_VIEW (view->web_view), steps);
/* Force the speed dial to kick in if going back to a blank page */
if (midori_view_is_blank (view))
midori_view_set_uri (view, "");
}
/**
* midori_view_can_go_back_or_forward
* @view: a #MidoriView
* @steps: number of steps to jump in history
*
* Determines whether the view can go back or forward by number of steps.
*
* Since: 0.4.5
**/
gboolean
midori_view_can_go_back_or_forward (MidoriView* view,
gint steps)
{
g_return_val_if_fail (MIDORI_IS_VIEW (view), FALSE);
if (view->web_view)
return webkit_web_view_can_go_back_or_forward (WEBKIT_WEB_VIEW (view->web_view), steps);
else
return FALSE;
}
static gchar* static gchar*
midori_view_get_related_page (MidoriView* view, midori_view_get_related_page (MidoriView* view,
const gchar* rel, const gchar* rel,
@ -5430,6 +5653,15 @@ midori_view_search_text (MidoriView* view,
{ {
g_return_if_fail (MIDORI_IS_VIEW (view)); g_return_if_fail (MIDORI_IS_VIEW (view));
#if GTK_CHECK_VERSION (3, 2, 0)
if (gtk_widget_get_visible (view->overlay_find))
{
text = midori_findbar_get_text (MIDORI_FINDBAR (view->overlay_find));
webkit_web_view_search_text (WEBKIT_WEB_VIEW (view->web_view),
text, case_sensitive, forward, TRUE);
return;
}
#endif
g_signal_emit (view, signals[SEARCH_TEXT], 0, g_signal_emit (view, signals[SEARCH_TEXT], 0,
webkit_web_view_search_text (WEBKIT_WEB_VIEW (view->web_view), webkit_web_view_search_text (WEBKIT_WEB_VIEW (view->web_view),
text, case_sensitive, forward, TRUE), NULL); text, case_sensitive, forward, TRUE), NULL);
@ -5647,6 +5879,29 @@ midori_view_get_web_view (MidoriView* view)
return view->web_view; return view->web_view;
} }
/**
* midori_view_get_for_widget:
* @widget: a #GtkWidget
*
* Determines the view appropriate for the specified widget.
*
* Return value: a #MidoriView
*
* Since 0.4.5
**/
MidoriView*
midori_view_get_for_widget (GtkWidget* web_view)
{
GtkWidget* scrolled = gtk_widget_get_parent (web_view);
#if GTK_CHECK_VERSION(3, 2, 0)
GtkWidget* overlay = gtk_widget_get_parent (scrolled);
GtkWidget* view = gtk_widget_get_parent (overlay);
#else
GtkWidget* view = gtk_widget_get_parent (scrolled);
#endif
return MIDORI_VIEW (view);
}
/** /**
* midori_view_get_security * midori_view_get_security
* @view: a #MidoriView * @view: a #MidoriView

View file

@ -96,6 +96,10 @@ void
midori_view_set_uri (MidoriView* view, midori_view_set_uri (MidoriView* view,
const gchar* uri); const gchar* uri);
void
midori_view_set_overlay_text (MidoriView* view,
const gchar* text);
gboolean gboolean
midori_view_is_blank (MidoriView* view); midori_view_is_blank (MidoriView* view);
@ -179,6 +183,14 @@ midori_view_can_go_forward (MidoriView* view);
void void
midori_view_go_forward (MidoriView* view); midori_view_go_forward (MidoriView* view);
void midori_view_go_back_or_forward (MidoriView* view,
gint steps);
gboolean
midori_view_can_go_back_or_forward (MidoriView* view,
gint steps);
const gchar* const gchar*
midori_view_get_previous_page (MidoriView* view); midori_view_get_previous_page (MidoriView* view);
@ -236,6 +248,9 @@ midori_view_get_snapshot (MidoriView* view,
GtkWidget* GtkWidget*
midori_view_get_web_view (MidoriView* view); midori_view_get_web_view (MidoriView* view);
MidoriView*
midori_view_get_for_widget (GtkWidget* web_view);
MidoriSecurity MidoriSecurity
midori_view_get_security (MidoriView* view); midori_view_get_security (MidoriView* view);

View file

@ -26,6 +26,10 @@
#if defined (G_OS_UNIX) #if defined (G_OS_UNIX)
#include <sys/utsname.h> #include <sys/utsname.h>
#endif #endif
#if defined(__FreeBSD__)
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
struct _MidoriWebSettings struct _MidoriWebSettings
{ {
@ -347,6 +351,21 @@ midori_get_download_dir (void)
static gboolean static gboolean
midori_web_settings_low_memory_profile () midori_web_settings_low_memory_profile ()
{ {
#ifdef _WIN32
/* See http://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx */
MEMORYSTATUSEX mem;
mem.dwLength = sizeof (mem);
if (GlobalMemoryStatusEx (&mem))
return mem.ullTotalPhys / 1024 / 1024 < 352;
#elif defined(__FreeBSD__)
size_t size;
int mem_total;
size = sizeof mem_total;
sysctlbyname("hw.realmem", &mem_total, &size, NULL, 0);
return mem_total / 1048576 < 352;
#else
gchar* contents; gchar* contents;
const gchar* total; const gchar* total;
if (!g_file_get_contents ("/proc/meminfo", &contents, NULL, NULL)) if (!g_file_get_contents ("/proc/meminfo", &contents, NULL, NULL))
@ -357,6 +376,7 @@ midori_web_settings_low_memory_profile ()
gdouble mem_total = g_ascii_strtoll (value, NULL, 0); gdouble mem_total = g_ascii_strtoll (value, NULL, 0);
return mem_total / 1024.0 < 352 + 1; return mem_total / 1024.0 < 352 + 1;
} }
#endif
return FALSE; return FALSE;
} }
@ -648,8 +668,13 @@ midori_web_settings_class_init (MidoriWebSettingsClass* class)
"always-show-tabbar", "always-show-tabbar",
_("Always Show Tabbar"), _("Always Show Tabbar"),
_("Always show the tabbar"), _("Always show the tabbar"),
FALSE, TRUE,
flags)); #ifdef HAVE_GRANITE
G_PARAM_READABLE
#else
flags
#endif
));
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_CLOSE_BUTTONS_ON_TABS, PROP_CLOSE_BUTTONS_ON_TABS,
@ -1202,6 +1227,14 @@ midori_web_settings_init (MidoriWebSettings* web_settings)
"* { -webkit-box-shadow: none !important; }"); "* { -webkit-box-shadow: none !important; }");
#endif #endif
#if defined (_WIN32) && WEBKIT_CHECK_VERSION (1, 7, 1)
/* Try to work-around black borders on native widgets and GTK+2 on Win32 */
midori_web_settings_add_style (web_settings, "black-widgets-workaround",
"input[type='checkbox'] { -webkit-appearance: checkbox !important }"
" input[type='radio'] { -webkit-appearance: radio !important }"
" * { -webkit-appearance: none !important }");
#endif
g_signal_connect (web_settings, "notify::default-encoding", g_signal_connect (web_settings, "notify::default-encoding",
G_CALLBACK (notify_default_encoding_cb), NULL); G_CALLBACK (notify_default_encoding_cb), NULL);
g_signal_connect (web_settings, "notify::default-font-family", g_signal_connect (web_settings, "notify::default-font-family",

View file

@ -115,6 +115,10 @@ namespace Midori {
public string version { get; set; } public string version { get; set; }
[NoAccessorMethod] [NoAccessorMethod]
public string authors { get; set; } public string authors { get; set; }
[NoAccessorMethod]
public string website { get; set; }
[NoAccessorMethod]
public string key { get; set; }
public signal void activate (Midori.App app); public signal void activate (Midori.App app);
public signal void deactivate (); public signal void deactivate ();
@ -163,6 +167,9 @@ namespace Midori {
public WebSettings settings { get; set; } public WebSettings settings { get; set; }
public GLib.Object net { get; } public GLib.Object net { get; }
[HasEmitter]
public signal bool download_requested (WebKit.Download download);
} }
public class WebSettings : WebKit.WebSettings { public class WebSettings : WebKit.WebSettings {

View file

@ -31,6 +31,7 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <glib/gprintf.h> #include <glib/gprintf.h>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <webkit/webkit.h>
#ifdef HAVE_HILDON_FM #ifdef HAVE_HILDON_FM
#include <hildon/hildon-file-chooser-dialog.h> #include <hildon/hildon-file-chooser-dialog.h>
@ -286,71 +287,12 @@ sokoke_show_uri (GdkScreen* screen,
return hildon_uri_open (uri, action, error); return hildon_uri_open (uri, action, error);
#elif defined (G_OS_WIN32) #elif defined (G_OS_WIN32)
CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
SHELLEXECUTEINFO info = { sizeof (info) };
info.nShow = SW_SHOWNORMAL;
info.lpFile = uri;
const gchar* fallbacks [] = { "explorer" }; return ShellExecuteEx (&info);
gsize i;
GAppInfo *app_info;
GFile *file;
gchar *free_uri;
g_return_val_if_fail (GDK_IS_SCREEN (screen) || !screen, FALSE);
g_return_val_if_fail (uri != NULL, FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
file = g_file_new_for_uri (uri);
app_info = g_file_query_default_handler (file, NULL, error);
if (app_info != NULL)
{
GdkAppLaunchContext *context;
gboolean result;
GList l;
context = gdk_app_launch_context_new ();
gdk_app_launch_context_set_screen (context, screen);
gdk_app_launch_context_set_timestamp (context, timestamp);
l.data = (char *)file;
l.next = l.prev = NULL;
result = g_app_info_launch (app_info, &l, (GAppLaunchContext*)context, error);
g_object_unref (context);
g_object_unref (app_info);
g_object_unref (file);
if (result)
return TRUE;
}
else
g_object_unref (file);
free_uri = g_filename_from_uri (uri, NULL, NULL);
if (free_uri)
{
gchar *quoted = g_shell_quote (free_uri);
uri = quoted;
g_free (free_uri);
free_uri = quoted;
}
for (i = 0; i < G_N_ELEMENTS (fallbacks); i++)
{
gchar* command = g_strconcat (fallbacks[i], " ", uri, NULL);
gboolean result = g_spawn_command_line_async (command, error);
g_free (command);
if (result)
{
g_free (free_uri);
return TRUE;
}
if (error)
*error = NULL;
}
g_free (free_uri);
return FALSE;
#else #else
#if !GLIB_CHECK_VERSION (2, 28, 0) #if !GLIB_CHECK_VERSION (2, 28, 0)
@ -1791,3 +1733,17 @@ sokoke_entry_set_clear_button_visible (GtkEntry* entry,
} }
} }
gchar*
sokoke_get_download_filename (WebKitDownload* download)
{
/* https://bugs.webkit.org/show_bug.cgi?id=83161 */
/* https://d19vezwu8eufl6.cloudfront.net/nlp/slides%2F03-01-FormalizingNB.pdf */
gchar* filename = g_strdup (webkit_download_get_suggested_filename (download));
#ifdef G_OS_WIN32
g_strdelimit (filename, "/\\<>:\"|?*", '_');
#else
g_strdelimit (filename, "/", '_');
#endif
return filename;
}

View file

@ -14,6 +14,7 @@
#define __SOKOKE_H__ 1 #define __SOKOKE_H__ 1
#include <JavaScriptCore/JavaScript.h> #include <JavaScriptCore/JavaScript.h>
#include <webkit/webkit.h>
#include <midori/midori-websettings.h> #include <midori/midori-websettings.h>
#include <katze/gtk3-compat.h> #include <katze/gtk3-compat.h>
@ -175,6 +176,8 @@ sokoke_accept_languages (const gchar* const * lang_names);
gboolean gboolean
sokoke_recursive_fork_protection (const gchar* uri, sokoke_recursive_fork_protection (const gchar* uri,
gboolean set_uri); gboolean set_uri);
gchar*
sokoke_get_download_filename (WebKitDownload* download);
typedef struct typedef struct
{ {

View file

@ -8,7 +8,7 @@ import platform
progressive = True progressive = True
libs = 'M UNIQUE LIBSOUP GMODULE GTHREAD LIBIDN GIO GTK SQLITE ' \ libs = 'M UNIQUE LIBSOUP GMODULE GTHREAD LIBIDN GIO GTK SQLITE ' \
'LIBNOTIFY WEBKIT JAVASCRIPTCOREGTK LIBXML X11 XSS WS2_32 HILDON' \ 'LIBNOTIFY WEBKIT JAVASCRIPTCOREGTK LIBXML X11 XSS WS2_32 HILDON' \
'HILDON_FM' 'HILDON_FM GRANITE'
if progressive or Options.commands['check']: if progressive or Options.commands['check']:
obj = bld.new_task_gen ('cc', 'staticlib') obj = bld.new_task_gen ('cc', 'staticlib')

View file

@ -29,7 +29,8 @@ gboolean
midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
KatzeItem* bookmark, KatzeItem* bookmark,
gboolean new_bookmark, gboolean new_bookmark,
gboolean is_folder); gboolean is_folder,
GtkWidget* proxy);
void void
midori_browser_open_bookmark (MidoriBrowser* browser, midori_browser_open_bookmark (MidoriBrowser* browser,
@ -341,9 +342,9 @@ midori_bookmarks_add_clicked_cb (GtkWidget* toolitem)
MidoriBrowser* browser = midori_browser_get_for_widget (toolitem); MidoriBrowser* browser = midori_browser_get_for_widget (toolitem);
/* FIXME: Take selected folder into account */ /* FIXME: Take selected folder into account */
if (g_str_equal (gtk_widget_get_name (toolitem), "BookmarkFolderAdd")) if (g_str_equal (gtk_widget_get_name (toolitem), "BookmarkFolderAdd"))
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, TRUE); midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, TRUE, toolitem);
else else
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE); midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE, toolitem);
} }
static void static void
@ -365,7 +366,7 @@ midori_bookmarks_edit_clicked_cb (GtkWidget* toolitem,
browser = midori_browser_get_for_widget (bookmarks->treeview); browser = midori_browser_get_for_widget (bookmarks->treeview);
midori_browser_edit_bookmark_dialog_new ( midori_browser_edit_bookmark_dialog_new (
browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item)); browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL);
g_object_unref (item); g_object_unref (item);
} }
} }

View file

@ -28,7 +28,8 @@ void
midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
KatzeItem* bookmark, KatzeItem* bookmark,
gboolean new_bookmark, gboolean new_bookmark,
gboolean is_folder); gboolean is_folder,
GtkWidget* proxy);
struct _MidoriHistory struct _MidoriHistory
@ -373,6 +374,7 @@ midori_history_bookmark_add_cb (GtkWidget* menuitem,
GtkTreeIter iter; GtkTreeIter iter;
KatzeItem* item = NULL; KatzeItem* item = NULL;
GtkWidget* proxy = GTK_IS_TOOL_ITEM (menuitem) ? menuitem : NULL;
MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (history)); MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (history));
if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (history->treeview), if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (history->treeview),
&model, &iter)) &model, &iter))
@ -380,11 +382,11 @@ midori_history_bookmark_add_cb (GtkWidget* menuitem,
if (KATZE_IS_ITEM (item) && katze_item_get_uri (item)) if (KATZE_IS_ITEM (item) && katze_item_get_uri (item))
{ {
midori_browser_edit_bookmark_dialog_new (browser, item, TRUE, FALSE); midori_browser_edit_bookmark_dialog_new (browser, item, TRUE, FALSE, proxy);
g_object_unref (item); g_object_unref (item);
} }
else else
midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE); midori_browser_edit_bookmark_dialog_new (browser, NULL, TRUE, FALSE, proxy);
} }
static GtkWidget* static GtkWidget*

View file

@ -257,6 +257,7 @@ midori_transfers_treeview_render_text_cb (GtkTreeViewColumn* column,
gchar* total; gchar* total;
gchar* size_text; gchar* size_text;
gchar* text; gchar* text;
gchar* filename;
gdouble progress; gdouble progress;
gtk_tree_model_get (model, iter, 1, &download, -1); gtk_tree_model_get (model, iter, 1, &download, -1);
@ -267,8 +268,9 @@ midori_transfers_treeview_render_text_cb (GtkTreeViewColumn* column,
size_text = g_strdup_printf (_("%s of %s"), current, total); size_text = g_strdup_printf (_("%s of %s"), current, total);
g_free (current); g_free (current);
g_free (total); g_free (total);
text = g_strdup_printf ("%s\n%s", filename = sokoke_get_download_filename (download);
webkit_download_get_suggested_filename (download), size_text); text = g_strdup_printf ("%s\n%s", filename, size_text);
g_free (filename);
g_free (size_text); g_free (size_text);
/* Avoid a bug in WebKit */ /* Avoid a bug in WebKit */
if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_CREATED) if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_CREATED)

View file

@ -522,7 +522,7 @@ msgid "Error downloading the image!"
msgstr "خطأ في تحميل الصورة!" msgstr "خطأ في تحميل الصورة!"
#: ../midori/midori-browser.c:1370 #: ../midori/midori-browser.c:1370
msgid "Can not downlaod selected image." msgid "Can not download selected image."
msgstr "لا يمكن تنزيل الصورة المحددة." msgstr "لا يمكن تنزيل الصورة المحددة."
#: ../midori/midori-browser.c:1473 #: ../midori/midori-browser.c:1473

1415
po/ca.po

File diff suppressed because it is too large Load diff

968
po/cs.po

File diff suppressed because it is too large Load diff

1126
po/da.po

File diff suppressed because it is too large Load diff

1020
po/de.po

File diff suppressed because it is too large Load diff

View file

@ -503,7 +503,7 @@ msgid "Error downloading the image!"
msgstr "Eraro dum elŝutado de bildo!" msgstr "Eraro dum elŝutado de bildo!"
#: ../midori/midori-browser.c:1339 #: ../midori/midori-browser.c:1339
msgid "Can not downlaod selected image." msgid "Can not download selected image."
msgstr "Ne povas elŝuti elektitan bildon." msgstr "Ne povas elŝuti elektitan bildon."
#: ../midori/midori-browser.c:1442 #: ../midori/midori-browser.c:1442

View file

@ -529,7 +529,7 @@ msgid "Error downloading the image!"
msgstr "Error al cargar el canal '%s'" msgstr "Error al cargar el canal '%s'"
#: ../midori/midori-browser.c:1369 #: ../midori/midori-browser.c:1369
msgid "Can not downlaod selected image." msgid "Can not download selected image."
msgstr "" msgstr ""
#: ../midori/midori-browser.c:1472 #: ../midori/midori-browser.c:1472

1661
po/fr.po

File diff suppressed because it is too large Load diff

1686
po/gl.po

File diff suppressed because it is too large Load diff

1319
po/he.po

File diff suppressed because it is too large Load diff

1234
po/hr.po

File diff suppressed because it is too large Load diff

View file

@ -523,7 +523,7 @@ msgid "Error downloading the image!"
msgstr "Hiba a kép letöltésekor" msgstr "Hiba a kép letöltésekor"
#: ../midori/midori-browser.c:1369 #: ../midori/midori-browser.c:1369
msgid "Can not downlaod selected image." msgid "Can not download selected image."
msgstr "A kijelölt kép nem tölthető le." msgstr "A kijelölt kép nem tölthető le."
#: ../midori/midori-browser.c:1472 #: ../midori/midori-browser.c:1472

962
po/id.po

File diff suppressed because it is too large Load diff

910
po/it.po

File diff suppressed because it is too large Load diff

1315
po/ja.po

File diff suppressed because it is too large Load diff

826
po/ko.po

File diff suppressed because it is too large Load diff

1056
po/lt.po

File diff suppressed because it is too large Load diff

813
po/nl.po

File diff suppressed because it is too large Load diff

1197
po/pl.po

File diff suppressed because it is too large Load diff

944
po/pt.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1151
po/ro.po

File diff suppressed because it is too large Load diff

1044
po/ru.po

File diff suppressed because it is too large Load diff

793
po/sk.po

File diff suppressed because it is too large Load diff

982
po/tr.po

File diff suppressed because it is too large Load diff

794
po/uk.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -166,13 +166,25 @@ extension_settings (void)
static void static void
extension_activate (gconstpointer data) extension_activate (gconstpointer data)
{ {
MidoriExtension* extension;
MidoriApp* app = midori_app_new (); MidoriApp* app = midori_app_new ();
MidoriExtension* extension = MIDORI_EXTENSION (data);
if (extension == NULL)
return;
g_object_set (app, "settings", midori_web_settings_new (), NULL); g_object_set (app, "settings", midori_web_settings_new (), NULL);
g_signal_emit_by_name (extension, "activate", app);
midori_extension_deactivate (extension); if (MIDORI_IS_EXTENSION (data))
{
extension = MIDORI_EXTENSION (data);
g_signal_emit_by_name (extension, "activate", app);
midori_extension_deactivate (extension);
}
else if (KATZE_IS_ARRAY (data))
{
KATZE_ARRAY_FOREACH_ITEM (extension, KATZE_ARRAY (data))
{
g_signal_emit_by_name (extension, "activate", app);
midori_extension_deactivate (extension);
}
}
g_object_unref (app); g_object_unref (app);
} }

View file

@ -31,10 +31,10 @@ for test in tests:
obj = bld.new_task_gen ('cc', 'program') obj = bld.new_task_gen ('cc', 'program')
obj.target = 'test-' + target obj.target = 'test-' + target
obj.includes = '.. ../midori ../panels' obj.includes = '.. ../midori ../panels'
obj.cflags = ['-DEXTENSION_PATH="' + os.path.abspath ('_build_/default/extensions') + '"'] obj.cflags = ['-DEXTENSION_PATH="' + os.path.abspath ('_build/default/extensions') + '"']
obj.source = source obj.source = source
obj.vapi_dirs = '../midori' obj.vapi_dirs = '../midori'
obj.packages = 'glib-2.0 gio-2.0 gtk+-2.0 libsoup-2.4 webkit-1.0 midori' obj.packages = 'glib-2.0 gio-2.0 gtk+-2.0 libsoup-2.4 webkit-1.0 midori'
obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML' obj.uselib = 'UNIQUE LIBSOUP GIO GTK SQLITE WEBKIT LIBXML GRANITE'
obj.uselib_local = 'midori-core' obj.uselib_local = 'midori-core'
obj.unit_test = 1 obj.unit_test = 1

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2008-2010 Christian Dywan <christian@twotoasts.de> Copyright (C) 2008-2012 Christian Dywan <christian@twotoasts.de>
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -97,7 +97,7 @@ midori_findbar_find_key_press_event_cb (MidoriFindbar* findbar,
else if (event->keyval == GDK_KEY_Return else if (event->keyval == GDK_KEY_Return
&& (event->state & GDK_SHIFT_MASK)) && (event->state & GDK_SHIFT_MASK))
{ {
midori_findbar_find (findbar, FALSE); midori_findbar_find_text (findbar, NULL, FALSE);
return TRUE; return TRUE;
} }
@ -141,16 +141,43 @@ midori_findbar_find_text (MidoriFindbar* findbar,
if (!(view = midori_browser_get_current_tab (browser))) if (!(view = midori_browser_get_current_tab (browser)))
return; return;
if (text == NULL)
text = gtk_entry_get_text (GTK_ENTRY (findbar->find_text));
case_sensitive = midori_findbar_case_sensitive (findbar); case_sensitive = midori_findbar_case_sensitive (findbar);
midori_view_search_text (MIDORI_VIEW (view), text, case_sensitive, forward); midori_view_search_text (MIDORI_VIEW (view), text, case_sensitive, forward);
} }
/**
* midori_findbar_get_text:
* @findbar: #MidoriFindbar
*
* Returns: the text typed in the entry
*
* Since: 0.4.5
**/
const gchar*
midori_findbar_get_text (MidoriFindbar* findbar)
{
g_return_val_if_fail (MIDORI_IS_FINDBAR (findbar), NULL);
return gtk_entry_get_text (GTK_ENTRY (findbar->find_text));
}
/**
* midori_findbar_find:
* @findbar: #MidoriFindbar
* @forward: %TRUE to search forward
*
* Advance to the next match.
*
* Deprecated: 0.4.5: Use midori_findbar_find_text() instead.
**/
void void
midori_findbar_find (MidoriFindbar* findbar, midori_findbar_find (MidoriFindbar* findbar,
gboolean forward) gboolean forward)
{ {
const gchar* text = gtk_entry_get_text (GTK_ENTRY (findbar->find_text)); midori_findbar_find_text (findbar, NULL, forward);
midori_findbar_find_text (findbar, text, forward);
} }
void void
@ -179,14 +206,14 @@ static void
midori_findbar_next_activate_cb (GtkWidget* entry, midori_findbar_next_activate_cb (GtkWidget* entry,
MidoriFindbar* findbar) MidoriFindbar* findbar)
{ {
midori_findbar_find (findbar, TRUE); midori_findbar_find_text (findbar, NULL, TRUE);
} }
static void static void
midori_findbar_previous_clicked_cb (GtkWidget* entry, midori_findbar_previous_clicked_cb (GtkWidget* entry,
MidoriFindbar* findbar) MidoriFindbar* findbar)
{ {
midori_findbar_find (findbar, FALSE); midori_findbar_find_text (findbar, NULL, FALSE);
} }
static void static void
@ -253,6 +280,7 @@ midori_findbar_init (MidoriFindbar* findbar)
#endif #endif
gtk_toolbar_set_icon_size (GTK_TOOLBAR (findbar), GTK_ICON_SIZE_MENU); gtk_toolbar_set_icon_size (GTK_TOOLBAR (findbar), GTK_ICON_SIZE_MENU);
gtk_toolbar_set_style (GTK_TOOLBAR (findbar), GTK_TOOLBAR_BOTH_HORIZ); gtk_toolbar_set_style (GTK_TOOLBAR (findbar), GTK_TOOLBAR_BOTH_HORIZ);
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (findbar), FALSE);
g_signal_connect (findbar, "key-press-event", g_signal_connect (findbar, "key-press-event",
G_CALLBACK (midori_findbar_find_key_press_event_cb), NULL); G_CALLBACK (midori_findbar_find_key_press_event_cb), NULL);
@ -336,7 +364,7 @@ void
midori_findbar_search_text (MidoriFindbar* findbar, midori_findbar_search_text (MidoriFindbar* findbar,
GtkWidget* view, GtkWidget* view,
gboolean found, gboolean found,
gchar* typing) const gchar* typing)
{ {
const gchar* text; const gchar* text;
gboolean case_sensitive; gboolean case_sensitive;

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2010 Christian Dywan <christian@twotoasts.de> Copyright (C) 2012 Christian Dywan <christian@twotoasts.de>
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -47,6 +47,9 @@ midori_findbar_find_text (MidoriFindbar* findbar,
const gchar* text, const gchar* text,
gboolean forward); gboolean forward);
const gchar*
midori_findbar_get_text (MidoriFindbar* findbar);
void void
midori_findbar_set_can_find (MidoriFindbar* findbar, midori_findbar_set_can_find (MidoriFindbar* findbar,
gboolean can_find); gboolean can_find);
@ -55,7 +58,7 @@ void
midori_findbar_search_text (MidoriFindbar* findbar, midori_findbar_search_text (MidoriFindbar* findbar,
GtkWidget* view, GtkWidget* view,
gboolean found, gboolean found,
gchar* typing); const gchar* typing);
void void
midori_findbar_set_close_button_left (MidoriFindbar* findbar, midori_findbar_set_close_button_left (MidoriFindbar* findbar,

View file

@ -262,8 +262,11 @@ midori_transferbar_add_download_item (MidoriTransferbar* transferbar,
g_free (path); g_free (path);
} }
else else
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress), {
webkit_download_get_suggested_filename (download)); gchar* filename = sokoke_get_download_filename (download);
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress), filename);
g_free (filename);
}
sokoke_widget_get_text_size (progress, "M", &width, NULL); sokoke_widget_get_text_size (progress, "M", &width, NULL);
gtk_widget_set_size_request (progress, width * 10, 1); gtk_widget_set_size_request (progress, width * 10, 1);
/* Avoid a bug in WebKit */ /* Avoid a bug in WebKit */
@ -377,7 +380,7 @@ midori_transferbar_confirm_delete (MidoriTransferbar* transferbar)
} }
if (dialog != NULL) if (dialog != NULL)
{ {
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_CANCEL) if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT)
cancel = TRUE; cancel = TRUE;
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
} }

View file

@ -19,7 +19,7 @@ LOG=~/.midori.out
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
BIN=_build_/default/midori/midori BIN=_build/default/midori/midori
BASENAME=`basename $0` BASENAME=`basename $0`
ulimit -c unlimited ulimit -c unlimited

View file

@ -43,7 +43,7 @@ gunzip -N $DOWNLOAD_PATH/other.xml
rm packages.version rm packages.version
touch packages.version touch packages.version
# downlaod all packages # download all packages
while read line while read line
do do
VERSION=`xmlgrep -c -f $DOWNLOAD_PATH/other.xml otherdata.package:name="$line":arch="$REPO_ARCH" | awk -F\< '{print $2}' |sed -e 'h' -e 's/^.*ver="\([^"]*\)".*$/\1/p' -e 'g' -e 's/^.*rel="\([^"]*\)".*$/\1/' | sed -e N -e 's/\n/-/' | sort -V -r | head -n 1` VERSION=`xmlgrep -c -f $DOWNLOAD_PATH/other.xml otherdata.package:name="$line":arch="$REPO_ARCH" | awk -F\< '{print $2}' |sed -e 'h' -e 's/^.*ver="\([^"]*\)".*$/\1/p' -e 'g' -e 's/^.*rel="\([^"]*\)".*$/\1/' | sed -e N -e 's/\n/-/' | sort -V -r | head -n 1`

62
wscript
View file

@ -29,7 +29,7 @@ from Configure import find_program_impl
major = 0 major = 0
minor = 4 minor = 4
micro = 4 micro = 5
APPNAME = 'midori' APPNAME = 'midori'
VERSION = VERSION_FULL = str (major) + '.' + str (minor) + '.' + str (micro) VERSION = VERSION_FULL = str (major) + '.' + str (minor) + '.' + str (micro)
@ -45,7 +45,7 @@ except:
pass pass
srcdir = '.' srcdir = '.'
blddir = '_build_' blddir = '_build' # recognized by ack
def option_enabled (option): def option_enabled (option):
if getattr (Options.options, 'enable_' + option): if getattr (Options.options, 'enable_' + option):
@ -92,9 +92,21 @@ def configure (conf):
conf.define (defname, dirvalue) conf.define (defname, dirvalue)
return dirvalue return dirvalue
def check_version (given_version, major, minor, micro):
if '.' in given_version:
given_major, given_minor, given_micro = given_version.split ('.')
else:
given_major, given_minor, given_micro = given_version
return int(given_major) > major or \
int(given_major) == major and int(given_minor) > minor or \
int(given_major) == major and int(given_minor) == minor and int(given_micro) >= micro
conf.check_tool ('compiler_cc') conf.check_tool ('compiler_cc')
conf.check_tool ('vala') conf.check_tool ('vala')
conf.check_tool ('glib2') conf.check_tool ('glib2')
if not check_version (conf.env['VALAC_VERSION'], 0, 14, 0):
Utils.pprint ('RED', 'Vala 0.14.0 or later is required.')
sys.exit (1)
if option_enabled ('nls'): if option_enabled ('nls'):
conf.check_tool ('intltool') conf.check_tool ('intltool')
@ -169,15 +181,6 @@ def configure (conf):
atleast_version=version, mandatory=mandatory) atleast_version=version, mandatory=mandatory)
return conf.env['HAVE_' + var] return conf.env['HAVE_' + var]
def check_version (given_version, major, minor, micro):
if '.' in given_version:
given_major, given_minor, given_micro = given_version.split ('.')
else:
given_major, given_minor, given_micro = given_version
return int(given_major) > major or \
int(given_major) == major and int(given_minor) > minor or \
int(given_major) == major and int(given_minor) == minor and int(given_micro) >= micro
if option_enabled ('unique'): if option_enabled ('unique'):
if option_enabled('gtk3'): unique_pkg = 'unique-3.0' if option_enabled('gtk3'): unique_pkg = 'unique-3.0'
else: unique_pkg = 'unique-1.0' else: unique_pkg = 'unique-1.0'
@ -206,6 +209,25 @@ def configure (conf):
conf.define ('LIBNOTIFY_VERSION', 'No') conf.define ('LIBNOTIFY_VERSION', 'No')
conf.define ('HAVE_LIBNOTIFY', [0,1][libnotify == 'yes']) conf.define ('HAVE_LIBNOTIFY', [0,1][libnotify == 'yes'])
if option_enabled ('granite'):
if not option_enabled ('gtk3'):
if getattr (Options.options, 'enable_granite'):
Utils.pprint ('RED', 'Granite requires --enable-gtk3')
sys.exit (1)
else:
granite = 'no (requires --enable-gtk3)'
else:
check_pkg ('granite', '0.1', False)
granite = ['N/A', 'yes'][conf.env['HAVE_GRANITE'] == 1]
if granite != 'yes':
option_checkfatal ('granite', 'new notebook, pop-overs')
conf.define ('GRANITE_VERSION', 'No')
else:
conf.define ('GRANITE_VERSION', conf.check_cfg (modversion='granite'))
else:
granite = 'no '
conf.define ('GRANITE_VERSION', 'No')
conf.check (lib='m', mandatory=True) conf.check (lib='m', mandatory=True)
check_pkg ('gmodule-2.0', '2.8.0', False) check_pkg ('gmodule-2.0', '2.8.0', False)
check_pkg ('gthread-2.0', '2.8.0', False) check_pkg ('gthread-2.0', '2.8.0', False)
@ -220,12 +242,6 @@ def configure (conf):
includes='/usr/X11R6/include', mandatory=False) includes='/usr/X11R6/include', mandatory=False)
conf.check (lib='Xss', libpath='/usr/X11R6/lib', mandatory=False) conf.check (lib='Xss', libpath='/usr/X11R6/lib', mandatory=False)
if option_enabled ('gtk3'): if option_enabled ('gtk3'):
if option_enabled ('addons') and not check_version (conf.env['VALAC_VERSION'], 0, 13, 2):
Utils.pprint ('RED', 'Vala 0.13.2 or later is required ' \
'to build with GTK+ 3 and extensions.\n' \
'Pass --disable-addons to build without extensions.\n' \
'Pass --disable-gtk3 to build with extensions and GTK+ 2.')
sys.exit (1)
check_pkg ('gtk+-3.0', '3.0.0', var='GTK', mandatory=False) check_pkg ('gtk+-3.0', '3.0.0', var='GTK', mandatory=False)
check_pkg ('webkitgtk-3.0', '1.1.17', var='WEBKIT', mandatory=False) check_pkg ('webkitgtk-3.0', '1.1.17', var='WEBKIT', mandatory=False)
if not conf.env['HAVE_GTK'] or not conf.env['HAVE_WEBKIT']: if not conf.env['HAVE_GTK'] or not conf.env['HAVE_WEBKIT']:
@ -242,12 +258,13 @@ def configure (conf):
check_pkg ('javascriptcoregtk-1.0', '1.5.1', args=args) check_pkg ('javascriptcoregtk-1.0', '1.5.1', args=args)
conf.env['HAVE_GTK3'] = option_enabled ('gtk3') conf.env['HAVE_GTK3'] = option_enabled ('gtk3')
check_pkg ('libsoup-2.4', '2.27.90') check_pkg ('libsoup-2.4', '2.27.90')
conf.define ('HAVE_LIBSOUP_2_25_2', 1)
conf.define ('HAVE_LIBSOUP_2_27_90', 1)
check_pkg ('libsoup-2.4', '2.29.3', False, var='LIBSOUP_2_29_3')
check_pkg ('libsoup-2.4', '2.29.91', False, var='LIBSOUP_2_29_91')
check_pkg ('libsoup-2.4', '2.37.1', False, var='LIBSOUP_2_37_1')
conf.define ('LIBSOUP_VERSION', conf.check_cfg (modversion='libsoup-2.4')) conf.define ('LIBSOUP_VERSION', conf.check_cfg (modversion='libsoup-2.4'))
if check_version (conf.env['LIBSOUP_VERSION'], 2, 29, 3):
conf.define ('LIBSOUP_2_29_3', 1)
if check_version (conf.env['LIBSOUP_VERSION'], 2, 29, 91):
conf.define ('LIBSOUP_2_29_91', 1)
if check_version (conf.env['LIBSOUP_VERSION'], 2, 37, 1):
conf.define ('LIBSOUP_2_37_1', 1)
check_pkg ('libxml-2.0', '2.6') check_pkg ('libxml-2.0', '2.6')
check_pkg ('sqlite3', '3.0', True, var='SQLITE') check_pkg ('sqlite3', '3.0', True, var='SQLITE')
@ -394,6 +411,7 @@ def set_options (opt):
group = opt.add_option_group ('Optional features', '') group = opt.add_option_group ('Optional features', '')
add_enable_option ('unique', 'single instance support', group, disable=is_win32 (os.environ)) add_enable_option ('unique', 'single instance support', group, disable=is_win32 (os.environ))
add_enable_option ('libnotify', 'notification support', group) add_enable_option ('libnotify', 'notification support', group)
add_enable_option ('granite', 'new notebook, pop-overs', group)
add_enable_option ('addons', 'building of extensions', group) add_enable_option ('addons', 'building of extensions', group)
add_enable_option ('tests', 'building of tests', group, disable=True) add_enable_option ('tests', 'building of tests', group, disable=True)
add_enable_option ('hildon', 'Maemo integration', group, disable=not is_maemo ()) add_enable_option ('hildon', 'Maemo integration', group, disable=not is_maemo ())