1 | /* |
2 | * Copyright (C) 2006, 2007 Apple Inc. |
3 | * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
4 | * Copyright (C) 2011 Igalia S.L. |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
17 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | * THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE) |
29 | #include "cmakeconfig.h" |
30 | #endif |
31 | #include "BrowserWindow.h" |
32 | |
33 | #include "BrowserDownloadsBar.h" |
34 | #include "BrowserSearchBar.h" |
35 | #include "BrowserSettingsDialog.h" |
36 | #include "BrowserTab.h" |
37 | #include <gdk/gdkkeysyms.h> |
38 | #include <string.h> |
39 | |
40 | struct _BrowserWindow { |
41 | GtkWindow parent; |
42 | |
43 | WebKitWebContext *webContext; |
44 | |
45 | GtkAccelGroup *accelGroup; |
46 | GtkWidget *mainBox; |
47 | GtkWidget *toolbar; |
48 | GtkWidget *uriEntry; |
49 | GtkWidget *backItem; |
50 | GtkWidget *forwardItem; |
51 | GtkWidget *zoomInItem; |
52 | GtkWidget *zoomOutItem; |
53 | GtkWidget *boldItem; |
54 | GtkWidget *italicItem; |
55 | GtkWidget *underlineItem; |
56 | GtkWidget *strikethroughItem; |
57 | GtkWidget *settingsDialog; |
58 | GtkWidget *notebook; |
59 | BrowserTab *activeTab; |
60 | GtkWidget *downloadsBar; |
61 | gboolean searchBarVisible; |
62 | gboolean fullScreenIsEnabled; |
63 | GdkPixbuf *favicon; |
64 | GtkWidget *reloadOrStopButton; |
65 | GtkWindow *parentWindow; |
66 | guint resetEntryProgressTimeoutId; |
67 | gchar *sessionFile; |
68 | GdkRGBA backgroundColor; |
69 | }; |
70 | |
71 | struct _BrowserWindowClass { |
72 | GtkWindowClass parent; |
73 | }; |
74 | |
75 | static const char *defaultWindowTitle = "WebKitGTK+ MiniBrowser" ; |
76 | static const gdouble minimumZoomLevel = 0.5; |
77 | static const gdouble maximumZoomLevel = 3; |
78 | static const gdouble defaultZoomLevel = 1; |
79 | static const gdouble zoomStep = 1.2; |
80 | static GList *windowList; |
81 | |
82 | G_DEFINE_TYPE(BrowserWindow, browser_window, GTK_TYPE_WINDOW) |
83 | |
84 | static char *getExternalURI(const char *uri) |
85 | { |
86 | /* From the user point of view we support about: prefix. */ |
87 | if (uri && g_str_has_prefix(uri, BROWSER_ABOUT_SCHEME)) |
88 | return g_strconcat("about" , uri + strlen(BROWSER_ABOUT_SCHEME), NULL); |
89 | |
90 | return g_strdup(uri); |
91 | } |
92 | |
93 | static void browserWindowSetStatusText(BrowserWindow *window, const char *text) |
94 | { |
95 | browser_tab_set_status_text(window->activeTab, text); |
96 | } |
97 | |
98 | static void resetStatusText(GtkWidget *widget, BrowserWindow *window) |
99 | { |
100 | browserWindowSetStatusText(window, NULL); |
101 | } |
102 | |
103 | static void activateUriEntryCallback(BrowserWindow *window) |
104 | { |
105 | browser_window_load_uri(window, gtk_entry_get_text(GTK_ENTRY(window->uriEntry))); |
106 | } |
107 | |
108 | static void reloadOrStopCallback(BrowserWindow *window) |
109 | { |
110 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
111 | if (webkit_web_view_is_loading(webView)) |
112 | webkit_web_view_stop_loading(webView); |
113 | else |
114 | webkit_web_view_reload(webView); |
115 | } |
116 | |
117 | static void goBackCallback(BrowserWindow *window) |
118 | { |
119 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
120 | webkit_web_view_go_back(webView); |
121 | } |
122 | |
123 | static void goForwardCallback(BrowserWindow *window) |
124 | { |
125 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
126 | webkit_web_view_go_forward(webView); |
127 | } |
128 | |
129 | static void settingsCallback(BrowserWindow *window) |
130 | { |
131 | if (window->settingsDialog) { |
132 | gtk_window_present(GTK_WINDOW(window->settingsDialog)); |
133 | return; |
134 | } |
135 | |
136 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
137 | window->settingsDialog = browser_settings_dialog_new(webkit_web_view_get_settings(webView)); |
138 | gtk_window_set_transient_for(GTK_WINDOW(window->settingsDialog), GTK_WINDOW(window)); |
139 | g_object_add_weak_pointer(G_OBJECT(window->settingsDialog), (gpointer *)&window->settingsDialog); |
140 | gtk_widget_show(window->settingsDialog); |
141 | } |
142 | |
143 | static void webViewURIChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window) |
144 | { |
145 | char *externalURI = getExternalURI(webkit_web_view_get_uri(webView)); |
146 | if (externalURI) { |
147 | gtk_entry_set_text(GTK_ENTRY(window->uriEntry), externalURI); |
148 | g_free(externalURI); |
149 | } else |
150 | gtk_entry_set_text(GTK_ENTRY(window->uriEntry), "" ); |
151 | } |
152 | |
153 | static void webViewTitleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window) |
154 | { |
155 | const char *title = webkit_web_view_get_title(webView); |
156 | if (!title) |
157 | title = defaultWindowTitle; |
158 | char *privateTitle = NULL; |
159 | if (webkit_web_view_is_controlled_by_automation(webView)) |
160 | privateTitle = g_strdup_printf("[Automation] %s" , title); |
161 | else if (webkit_web_view_is_ephemeral(webView)) |
162 | privateTitle = g_strdup_printf("[Private] %s" , title); |
163 | gtk_window_set_title(GTK_WINDOW(window), privateTitle ? privateTitle : title); |
164 | g_free(privateTitle); |
165 | } |
166 | |
167 | static gboolean resetEntryProgress(BrowserWindow *window) |
168 | { |
169 | gtk_entry_set_progress_fraction(GTK_ENTRY(window->uriEntry), 0); |
170 | window->resetEntryProgressTimeoutId = 0; |
171 | return FALSE; |
172 | } |
173 | |
174 | static void webViewLoadProgressChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window) |
175 | { |
176 | gdouble progress = webkit_web_view_get_estimated_load_progress(webView); |
177 | gtk_entry_set_progress_fraction(GTK_ENTRY(window->uriEntry), progress); |
178 | if (progress == 1.0) { |
179 | window->resetEntryProgressTimeoutId = g_timeout_add(500, (GSourceFunc)resetEntryProgress, window); |
180 | g_source_set_name_by_id(window->resetEntryProgressTimeoutId, "[WebKit] resetEntryProgress" ); |
181 | } else if (window->resetEntryProgressTimeoutId) { |
182 | g_source_remove(window->resetEntryProgressTimeoutId); |
183 | window->resetEntryProgressTimeoutId = 0; |
184 | } |
185 | } |
186 | |
187 | static void downloadStarted(WebKitWebContext *webContext, WebKitDownload *download, BrowserWindow *window) |
188 | { |
189 | if (!window->downloadsBar) { |
190 | window->downloadsBar = browser_downloads_bar_new(); |
191 | gtk_box_pack_start(GTK_BOX(window->mainBox), window->downloadsBar, FALSE, FALSE, 0); |
192 | gtk_box_reorder_child(GTK_BOX(window->mainBox), window->downloadsBar, 0); |
193 | g_object_add_weak_pointer(G_OBJECT(window->downloadsBar), (gpointer *)&(window->downloadsBar)); |
194 | gtk_widget_show(window->downloadsBar); |
195 | } |
196 | browser_downloads_bar_add_download(BROWSER_DOWNLOADS_BAR(window->downloadsBar), download); |
197 | } |
198 | |
199 | static void browserWindowHistoryItemSelected(BrowserWindow *window, GtkMenuItem *item) |
200 | { |
201 | GtkAction *action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(item)); |
202 | browserWindowSetStatusText(window, action ? gtk_action_get_name(action) : NULL); |
203 | } |
204 | |
205 | static void browserWindowHistoryItemActivated(BrowserWindow *window, GtkAction *action) |
206 | { |
207 | WebKitBackForwardListItem *item = g_object_get_data(G_OBJECT(action), "back-forward-list-item" ); |
208 | if (!item) |
209 | return; |
210 | |
211 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
212 | webkit_web_view_go_to_back_forward_list_item(webView, item); |
213 | } |
214 | |
215 | static GtkWidget *(BrowserWindow *window, GList *list) |
216 | { |
217 | if (!list) |
218 | return NULL; |
219 | |
220 | GtkWidget * = gtk_menu_new(); |
221 | GList *listItem; |
222 | for (listItem = list; listItem; listItem = g_list_next(listItem)) { |
223 | WebKitBackForwardListItem *item = (WebKitBackForwardListItem *)listItem->data; |
224 | const char *uri = webkit_back_forward_list_item_get_uri(item); |
225 | const char *title = webkit_back_forward_list_item_get_title(item); |
226 | |
227 | GtkAction *action = gtk_action_new(uri, title, NULL, NULL); |
228 | g_object_set_data_full(G_OBJECT(action), "back-forward-list-item" , g_object_ref(item), g_object_unref); |
229 | g_signal_connect_swapped(action, "activate" , G_CALLBACK(browserWindowHistoryItemActivated), window); |
230 | |
231 | GtkWidget * = gtk_action_create_menu_item(action); |
232 | g_signal_connect_swapped(menuItem, "select" , G_CALLBACK(browserWindowHistoryItemSelected), window); |
233 | g_object_unref(action); |
234 | |
235 | gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuItem); |
236 | gtk_widget_show(menuItem); |
237 | } |
238 | |
239 | g_signal_connect(menu, "hide" , G_CALLBACK(resetStatusText), window); |
240 | |
241 | return menu; |
242 | } |
243 | |
244 | static void browserWindowUpdateNavigationActions(BrowserWindow *window, WebKitBackForwardList *backForwardlist) |
245 | { |
246 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
247 | gtk_widget_set_sensitive(window->backItem, webkit_web_view_can_go_back(webView)); |
248 | gtk_widget_set_sensitive(window->forwardItem, webkit_web_view_can_go_forward(webView)); |
249 | |
250 | GList *list = g_list_reverse(webkit_back_forward_list_get_back_list_with_limit(backForwardlist, 10)); |
251 | gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(window->backItem), |
252 | browserWindowCreateBackForwardMenu(window, list)); |
253 | g_list_free(list); |
254 | |
255 | list = webkit_back_forward_list_get_forward_list_with_limit(backForwardlist, 10); |
256 | gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(window->forwardItem), |
257 | browserWindowCreateBackForwardMenu(window, list)); |
258 | g_list_free(list); |
259 | } |
260 | |
261 | static void browserWindowTryCloseCurrentWebView(BrowserWindow *window) |
262 | { |
263 | int currentPage = gtk_notebook_get_current_page(GTK_NOTEBOOK(window->notebook)); |
264 | BrowserTab *tab = (BrowserTab *)gtk_notebook_get_nth_page(GTK_NOTEBOOK(window->notebook), currentPage); |
265 | webkit_web_view_try_close(browser_tab_get_web_view(tab)); |
266 | } |
267 | |
268 | static void browserWindowTryClose(BrowserWindow *window) |
269 | { |
270 | GSList *webViews = NULL; |
271 | int n = gtk_notebook_get_n_pages(GTK_NOTEBOOK(window->notebook)); |
272 | int i; |
273 | |
274 | for (i = 0; i < n; ++i) { |
275 | BrowserTab *tab = (BrowserTab *)gtk_notebook_get_nth_page(GTK_NOTEBOOK(window->notebook), i); |
276 | webViews = g_slist_prepend(webViews, browser_tab_get_web_view(tab)); |
277 | } |
278 | |
279 | GSList *link; |
280 | for (link = webViews; link; link = link->next) |
281 | webkit_web_view_try_close(link->data); |
282 | } |
283 | |
284 | static void backForwardlistChanged(WebKitBackForwardList *backForwardlist, WebKitBackForwardListItem *itemAdded, GList *itemsRemoved, BrowserWindow *window) |
285 | { |
286 | browserWindowUpdateNavigationActions(window, backForwardlist); |
287 | } |
288 | |
289 | static void webViewClose(WebKitWebView *webView, BrowserWindow *window) |
290 | { |
291 | int tabsCount = gtk_notebook_get_n_pages(GTK_NOTEBOOK(window->notebook)); |
292 | if (tabsCount == 1) { |
293 | gtk_widget_destroy(GTK_WIDGET(window)); |
294 | return; |
295 | } |
296 | |
297 | int i; |
298 | for (i = 0; i < tabsCount; ++i) { |
299 | BrowserTab *tab = (BrowserTab *)gtk_notebook_get_nth_page(GTK_NOTEBOOK(window->notebook), i); |
300 | if (browser_tab_get_web_view(tab) == webView) { |
301 | gtk_widget_destroy(GTK_WIDGET(tab)); |
302 | return; |
303 | } |
304 | } |
305 | } |
306 | |
307 | static void webViewRunAsModal(WebKitWebView *webView, BrowserWindow *window) |
308 | { |
309 | gtk_window_set_modal(GTK_WINDOW(window), TRUE); |
310 | gtk_window_set_transient_for(GTK_WINDOW(window), window->parentWindow); |
311 | } |
312 | |
313 | static void webViewReadyToShow(WebKitWebView *webView, BrowserWindow *window) |
314 | { |
315 | WebKitWindowProperties *windowProperties = webkit_web_view_get_window_properties(webView); |
316 | |
317 | GdkRectangle geometry; |
318 | webkit_window_properties_get_geometry(windowProperties, &geometry); |
319 | if (geometry.x >= 0 && geometry.y >= 0) |
320 | gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y); |
321 | if (geometry.width > 0 && geometry.height > 0) |
322 | gtk_window_resize(GTK_WINDOW(window), geometry.width, geometry.height); |
323 | |
324 | if (!webkit_window_properties_get_toolbar_visible(windowProperties)) |
325 | gtk_widget_hide(window->toolbar); |
326 | else if (!webkit_window_properties_get_locationbar_visible(windowProperties)) |
327 | gtk_widget_hide(window->uriEntry); |
328 | |
329 | if (!webkit_window_properties_get_resizable(windowProperties)) |
330 | gtk_window_set_resizable(GTK_WINDOW(window), FALSE); |
331 | |
332 | gtk_widget_show(GTK_WIDGET(window)); |
333 | } |
334 | |
335 | static GtkWidget *webViewCreate(WebKitWebView *webView, WebKitNavigationAction *navigation, BrowserWindow *window) |
336 | { |
337 | WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_related_view(webView)); |
338 | webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView)); |
339 | |
340 | GtkWidget *newWindow = browser_window_new(GTK_WINDOW(window), window->webContext); |
341 | browser_window_append_view(BROWSER_WINDOW(newWindow), newWebView); |
342 | gtk_widget_grab_focus(GTK_WIDGET(newWebView)); |
343 | g_signal_connect(newWebView, "ready-to-show" , G_CALLBACK(webViewReadyToShow), newWindow); |
344 | g_signal_connect(newWebView, "run-as-modal" , G_CALLBACK(webViewRunAsModal), newWindow); |
345 | g_signal_connect(newWebView, "close" , G_CALLBACK(webViewClose), newWindow); |
346 | return GTK_WIDGET(newWebView); |
347 | } |
348 | |
349 | static gboolean webViewEnterFullScreen(WebKitWebView *webView, BrowserWindow *window) |
350 | { |
351 | gtk_widget_hide(window->toolbar); |
352 | browser_tab_enter_fullscreen(window->activeTab); |
353 | return FALSE; |
354 | } |
355 | |
356 | static gboolean webViewLeaveFullScreen(WebKitWebView *webView, BrowserWindow *window) |
357 | { |
358 | browser_tab_leave_fullscreen(window->activeTab); |
359 | gtk_widget_show(window->toolbar); |
360 | return FALSE; |
361 | } |
362 | |
363 | static gboolean webViewLoadFailed(WebKitWebView *webView, WebKitLoadEvent loadEvent, const char *failingURI, GError *error, BrowserWindow *window) |
364 | { |
365 | gtk_entry_set_progress_fraction(GTK_ENTRY(window->uriEntry), 0.); |
366 | return FALSE; |
367 | } |
368 | |
369 | static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, BrowserWindow *window) |
370 | { |
371 | if (decisionType != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION) |
372 | return FALSE; |
373 | |
374 | WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision)); |
375 | if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED |
376 | || webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE) |
377 | return FALSE; |
378 | |
379 | /* Multiple tabs are not allowed in editor mode. */ |
380 | if (webkit_web_view_is_editable(webView)) |
381 | return FALSE; |
382 | |
383 | /* Opening a new tab if link clicked with the middle button. */ |
384 | WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, |
385 | "web-context" , webkit_web_view_get_context(webView), |
386 | "settings" , webkit_web_view_get_settings(webView), |
387 | "user-content-manager" , webkit_web_view_get_user_content_manager(webView), |
388 | "is-controlled-by-automation" , webkit_web_view_is_controlled_by_automation(webView), |
389 | NULL)); |
390 | browser_window_append_view(window, newWebView); |
391 | webkit_web_view_load_request(newWebView, webkit_navigation_action_get_request(navigationAction)); |
392 | |
393 | webkit_policy_decision_ignore(decision); |
394 | return TRUE; |
395 | } |
396 | |
397 | static void webViewMouseTargetChanged(WebKitWebView *webView, WebKitHitTestResult *hitTestResult, guint mouseModifiers, BrowserWindow *window) |
398 | { |
399 | if (!webkit_hit_test_result_context_is_link(hitTestResult)) { |
400 | browserWindowSetStatusText(window, NULL); |
401 | return; |
402 | } |
403 | browserWindowSetStatusText(window, webkit_hit_test_result_get_link_uri(hitTestResult)); |
404 | } |
405 | |
406 | static gboolean browserWindowCanZoomIn(BrowserWindow *window) |
407 | { |
408 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
409 | gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) * zoomStep; |
410 | return zoomLevel < maximumZoomLevel; |
411 | } |
412 | |
413 | static gboolean browserWindowCanZoomOut(BrowserWindow *window) |
414 | { |
415 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
416 | gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) / zoomStep; |
417 | return zoomLevel > minimumZoomLevel; |
418 | } |
419 | |
420 | static gboolean browserWindowZoomIn(BrowserWindow *window) |
421 | { |
422 | if (browserWindowCanZoomIn(window)) { |
423 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
424 | gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) * zoomStep; |
425 | webkit_web_view_set_zoom_level(webView, zoomLevel); |
426 | return TRUE; |
427 | } |
428 | return FALSE; |
429 | } |
430 | |
431 | static gboolean browserWindowZoomOut(BrowserWindow *window) |
432 | { |
433 | if (browserWindowCanZoomOut(window)) { |
434 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
435 | gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) / zoomStep; |
436 | webkit_web_view_set_zoom_level(webView, zoomLevel); |
437 | return TRUE; |
438 | } |
439 | return FALSE; |
440 | } |
441 | |
442 | static gboolean scrollEventCallback(WebKitWebView *webView, const GdkEventScroll *event, BrowserWindow *window) |
443 | { |
444 | GdkModifierType mod = gtk_accelerator_get_default_mod_mask(); |
445 | |
446 | if ((event->state & mod) != GDK_CONTROL_MASK) |
447 | return FALSE; |
448 | |
449 | if (event->delta_y < 0) |
450 | return browserWindowZoomIn(window); |
451 | |
452 | return browserWindowZoomOut(window); |
453 | } |
454 | |
455 | static void browserWindowUpdateZoomActions(BrowserWindow *window) |
456 | { |
457 | gtk_widget_set_sensitive(window->zoomInItem, browserWindowCanZoomIn(window)); |
458 | gtk_widget_set_sensitive(window->zoomOutItem, browserWindowCanZoomOut(window)); |
459 | } |
460 | |
461 | static void webViewZoomLevelChanged(GObject *object, GParamSpec *paramSpec, BrowserWindow *window) |
462 | { |
463 | browserWindowUpdateZoomActions(window); |
464 | } |
465 | |
466 | static void updateUriEntryIcon(BrowserWindow *window) |
467 | { |
468 | GtkEntry *entry = GTK_ENTRY(window->uriEntry); |
469 | if (window->favicon) |
470 | gtk_entry_set_icon_from_pixbuf(entry, GTK_ENTRY_ICON_PRIMARY, window->favicon); |
471 | else |
472 | gtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_NEW); |
473 | } |
474 | |
475 | static void faviconChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserWindow *window) |
476 | { |
477 | GdkPixbuf *favicon = NULL; |
478 | cairo_surface_t *surface = webkit_web_view_get_favicon(webView); |
479 | |
480 | if (surface) { |
481 | int width = cairo_image_surface_get_width(surface); |
482 | int height = cairo_image_surface_get_height(surface); |
483 | favicon = gdk_pixbuf_get_from_surface(surface, 0, 0, width, height); |
484 | } |
485 | |
486 | if (window->favicon) |
487 | g_object_unref(window->favicon); |
488 | window->favicon = favicon; |
489 | |
490 | updateUriEntryIcon(window); |
491 | } |
492 | |
493 | static void webViewIsLoadingChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserWindow *window) |
494 | { |
495 | gboolean isLoading = webkit_web_view_is_loading(webView); |
496 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(window->reloadOrStopButton), isLoading ? "Stop" : "Reload" ); |
497 | gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(window->reloadOrStopButton), isLoading ? GTK_STOCK_STOP : GTK_STOCK_REFRESH); |
498 | } |
499 | |
500 | static void zoomInCallback(BrowserWindow *window) |
501 | { |
502 | browserWindowZoomIn(window); |
503 | } |
504 | |
505 | static void zoomOutCallback(BrowserWindow *window) |
506 | { |
507 | browserWindowZoomOut(window); |
508 | } |
509 | |
510 | static void defaultZoomCallback(BrowserWindow *window) |
511 | { |
512 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
513 | webkit_web_view_set_zoom_level(webView, defaultZoomLevel); |
514 | } |
515 | |
516 | static void searchCallback(BrowserWindow *window) |
517 | { |
518 | browser_tab_start_search(window->activeTab); |
519 | } |
520 | |
521 | static void newTabCallback(BrowserWindow *window) |
522 | { |
523 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
524 | if (webkit_web_view_is_editable(webView)) |
525 | return; |
526 | |
527 | browser_window_append_view(window, WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, |
528 | "web-context" , webkit_web_view_get_context(webView), |
529 | "settings" , webkit_web_view_get_settings(webView), |
530 | "user-content-manager" , webkit_web_view_get_user_content_manager(webView), |
531 | "is-controlled-by-automation" , webkit_web_view_is_controlled_by_automation(webView), |
532 | NULL))); |
533 | gtk_widget_grab_focus(window->uriEntry); |
534 | gtk_notebook_set_current_page(GTK_NOTEBOOK(window->notebook), -1); |
535 | } |
536 | |
537 | static void toggleWebInspector(BrowserWindow *window) |
538 | { |
539 | browser_tab_toggle_inspector(window->activeTab); |
540 | } |
541 | |
542 | static void openPrivateWindow(BrowserWindow *window) |
543 | { |
544 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
545 | WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, |
546 | "web-context" , webkit_web_view_get_context(webView), |
547 | "settings" , webkit_web_view_get_settings(webView), |
548 | "user-content-manager" , webkit_web_view_get_user_content_manager(webView), |
549 | "is-ephemeral" , TRUE, |
550 | "is-controlled-by-automation" , webkit_web_view_is_controlled_by_automation(webView), |
551 | NULL)); |
552 | GtkWidget *newWindow = browser_window_new(GTK_WINDOW(window), window->webContext); |
553 | browser_window_append_view(BROWSER_WINDOW(newWindow), newWebView); |
554 | gtk_widget_grab_focus(GTK_WIDGET(newWebView)); |
555 | gtk_widget_show(GTK_WIDGET(newWindow)); |
556 | } |
557 | |
558 | static void reloadPage(BrowserWindow *window) |
559 | { |
560 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
561 | webkit_web_view_reload(webView); |
562 | } |
563 | |
564 | static void reloadPageIgnoringCache(BrowserWindow *window) |
565 | { |
566 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
567 | webkit_web_view_reload_bypass_cache(webView); |
568 | } |
569 | |
570 | static void stopPageLoad(BrowserWindow *window) |
571 | { |
572 | browser_tab_stop_search(window->activeTab); |
573 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
574 | if (webkit_web_view_is_loading(webView)) |
575 | webkit_web_view_stop_loading(webView); |
576 | } |
577 | |
578 | static void loadHomePage(BrowserWindow *window) |
579 | { |
580 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
581 | webkit_web_view_load_uri(webView, BROWSER_DEFAULT_URL); |
582 | } |
583 | |
584 | static gboolean toggleFullScreen(BrowserWindow *window, gpointer user_data) |
585 | { |
586 | if (!window->fullScreenIsEnabled) { |
587 | gtk_window_fullscreen(GTK_WINDOW(window)); |
588 | gtk_widget_hide(window->toolbar); |
589 | window->fullScreenIsEnabled = TRUE; |
590 | } else { |
591 | gtk_window_unfullscreen(GTK_WINDOW(window)); |
592 | gtk_widget_show(window->toolbar); |
593 | window->fullScreenIsEnabled = FALSE; |
594 | } |
595 | return TRUE; |
596 | } |
597 | |
598 | static void webKitPrintOperationFailedCallback(WebKitPrintOperation *printOperation, GError *error) |
599 | { |
600 | g_warning("Print failed: '%s'" , error->message); |
601 | } |
602 | |
603 | static gboolean printPage(BrowserWindow *window, gpointer user_data) |
604 | { |
605 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
606 | WebKitPrintOperation *printOperation = webkit_print_operation_new(webView); |
607 | |
608 | g_signal_connect(printOperation, "failed" , G_CALLBACK(webKitPrintOperationFailedCallback), NULL); |
609 | webkit_print_operation_run_dialog(printOperation, GTK_WINDOW(window)); |
610 | g_object_unref(printOperation); |
611 | |
612 | return TRUE; |
613 | } |
614 | |
615 | static void editingCommandCallback(GtkWidget *widget, BrowserWindow *window) |
616 | { |
617 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
618 | webkit_web_view_execute_editing_command(webView, gtk_widget_get_name(widget)); |
619 | } |
620 | |
621 | static void insertImageCommandCallback(GtkWidget *widget, BrowserWindow *window) |
622 | { |
623 | GtkWidget *fileChooser = gtk_file_chooser_dialog_new("Insert Image" , GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, |
624 | "Cancel" , GTK_RESPONSE_CANCEL, "Open" , GTK_RESPONSE_ACCEPT, NULL); |
625 | |
626 | GtkFileFilter *filter = gtk_file_filter_new(); |
627 | gtk_file_filter_set_name(filter, "Images" ); |
628 | gtk_file_filter_add_pixbuf_formats(filter); |
629 | gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fileChooser), filter); |
630 | |
631 | if (gtk_dialog_run(GTK_DIALOG(fileChooser)) == GTK_RESPONSE_ACCEPT) { |
632 | char *uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(fileChooser)); |
633 | if (uri) { |
634 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
635 | webkit_web_view_execute_editing_command_with_argument(webView, WEBKIT_EDITING_COMMAND_INSERT_IMAGE, uri); |
636 | g_free(uri); |
637 | } |
638 | } |
639 | |
640 | gtk_widget_destroy(fileChooser); |
641 | } |
642 | |
643 | static void insertLinkCommandCallback(GtkWidget *widget, BrowserWindow *window) |
644 | { |
645 | GtkWidget *dialog = gtk_dialog_new_with_buttons("Insert Link" , GTK_WINDOW(window), GTK_DIALOG_MODAL, "Insert" , GTK_RESPONSE_ACCEPT, NULL); |
646 | gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); |
647 | GtkWidget *entry = gtk_entry_new(); |
648 | gtk_entry_set_placeholder_text(GTK_ENTRY(entry), "URL" ); |
649 | gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); |
650 | gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry); |
651 | gtk_widget_show(entry); |
652 | |
653 | if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { |
654 | const char *url = gtk_entry_get_text(GTK_ENTRY(entry)); |
655 | if (url && *url) { |
656 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
657 | webkit_web_view_execute_editing_command_with_argument(webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, url); |
658 | } |
659 | } |
660 | |
661 | gtk_widget_destroy(dialog); |
662 | } |
663 | |
664 | static void browserWindowEditingCommandToggleButtonSetActive(BrowserWindow *window, GtkWidget *button, gboolean active) |
665 | { |
666 | g_signal_handlers_block_by_func(button, G_CALLBACK(editingCommandCallback), window); |
667 | gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), active); |
668 | g_signal_handlers_unblock_by_func(button, G_CALLBACK(editingCommandCallback), window); |
669 | } |
670 | |
671 | static void typingAttributesChanged(WebKitEditorState *editorState, GParamSpec *spec, BrowserWindow *window) |
672 | { |
673 | unsigned typingAttributes = webkit_editor_state_get_typing_attributes(editorState); |
674 | browserWindowEditingCommandToggleButtonSetActive(window, window->boldItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD); |
675 | browserWindowEditingCommandToggleButtonSetActive(window, window->italicItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC); |
676 | browserWindowEditingCommandToggleButtonSetActive(window, window->underlineItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE); |
677 | browserWindowEditingCommandToggleButtonSetActive(window, window->strikethroughItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH); |
678 | } |
679 | |
680 | static void browserWindowFinalize(GObject *gObject) |
681 | { |
682 | BrowserWindow *window = BROWSER_WINDOW(gObject); |
683 | |
684 | g_signal_handlers_disconnect_matched(window->webContext, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window); |
685 | |
686 | if (window->favicon) { |
687 | g_object_unref(window->favicon); |
688 | window->favicon = NULL; |
689 | } |
690 | |
691 | if (window->accelGroup) { |
692 | g_object_unref(window->accelGroup); |
693 | window->accelGroup = NULL; |
694 | } |
695 | |
696 | if (window->resetEntryProgressTimeoutId) |
697 | g_source_remove(window->resetEntryProgressTimeoutId); |
698 | |
699 | g_free(window->sessionFile); |
700 | |
701 | windowList = g_list_remove(windowList, window); |
702 | |
703 | G_OBJECT_CLASS(browser_window_parent_class)->finalize(gObject); |
704 | |
705 | if (!windowList) |
706 | gtk_main_quit(); |
707 | } |
708 | |
709 | static void browserWindowSetupEditorToolbar(BrowserWindow *window) |
710 | { |
711 | GtkWidget *toolbar = gtk_toolbar_new(); |
712 | gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL); |
713 | gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH_HORIZ); |
714 | |
715 | GtkToolItem *item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_BOLD); |
716 | window->boldItem = GTK_WIDGET(item); |
717 | gtk_widget_set_name(GTK_WIDGET(item), "Bold" ); |
718 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Bold" ); |
719 | g_signal_connect(G_OBJECT(item), "toggled" , G_CALLBACK(editingCommandCallback), window); |
720 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
721 | gtk_widget_show(GTK_WIDGET(item)); |
722 | |
723 | item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_ITALIC); |
724 | window->italicItem = GTK_WIDGET(item); |
725 | gtk_widget_set_name(GTK_WIDGET(item), "Italic" ); |
726 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Italic" ); |
727 | g_signal_connect(G_OBJECT(item), "toggled" , G_CALLBACK(editingCommandCallback), window); |
728 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
729 | gtk_widget_show(GTK_WIDGET(item)); |
730 | |
731 | item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_UNDERLINE); |
732 | window->underlineItem = GTK_WIDGET(item); |
733 | gtk_widget_set_name(GTK_WIDGET(item), "Underline" ); |
734 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Underline" ); |
735 | g_signal_connect(G_OBJECT(item), "toggled" , G_CALLBACK(editingCommandCallback), window); |
736 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
737 | gtk_widget_show(GTK_WIDGET(item)); |
738 | |
739 | item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_STRIKETHROUGH); |
740 | gtk_widget_set_name(GTK_WIDGET(item), "Strikethrough" ); |
741 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Strikethrough" ); |
742 | window->strikethroughItem = GTK_WIDGET(item); |
743 | g_signal_connect(G_OBJECT(item), "toggled" , G_CALLBACK(editingCommandCallback), window); |
744 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
745 | gtk_widget_show(GTK_WIDGET(item)); |
746 | |
747 | item = gtk_separator_tool_item_new(); |
748 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
749 | gtk_widget_show(GTK_WIDGET(item)); |
750 | |
751 | item = gtk_tool_button_new_from_stock(GTK_STOCK_CUT); |
752 | gtk_widget_set_name(GTK_WIDGET(item), WEBKIT_EDITING_COMMAND_CUT); |
753 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), WEBKIT_EDITING_COMMAND_CUT); |
754 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(editingCommandCallback), window); |
755 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
756 | gtk_widget_show(GTK_WIDGET(item)); |
757 | |
758 | item = gtk_tool_button_new_from_stock(GTK_STOCK_COPY); |
759 | gtk_widget_set_name(GTK_WIDGET(item), WEBKIT_EDITING_COMMAND_COPY); |
760 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), WEBKIT_EDITING_COMMAND_COPY); |
761 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(editingCommandCallback), window); |
762 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
763 | gtk_widget_show(GTK_WIDGET(item)); |
764 | |
765 | item = gtk_tool_button_new_from_stock(GTK_STOCK_PASTE); |
766 | gtk_widget_set_name(GTK_WIDGET(item), WEBKIT_EDITING_COMMAND_PASTE); |
767 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), WEBKIT_EDITING_COMMAND_PASTE); |
768 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(editingCommandCallback), window); |
769 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
770 | gtk_widget_show(GTK_WIDGET(item)); |
771 | |
772 | item = gtk_separator_tool_item_new(); |
773 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
774 | gtk_widget_show(GTK_WIDGET(item)); |
775 | |
776 | item = gtk_tool_button_new_from_stock(GTK_STOCK_UNDO); |
777 | gtk_widget_set_name(GTK_WIDGET(item), WEBKIT_EDITING_COMMAND_UNDO); |
778 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), WEBKIT_EDITING_COMMAND_UNDO); |
779 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(editingCommandCallback), window); |
780 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
781 | gtk_widget_show(GTK_WIDGET(item)); |
782 | |
783 | item = gtk_tool_button_new_from_stock(GTK_STOCK_REDO); |
784 | gtk_widget_set_name(GTK_WIDGET(item), WEBKIT_EDITING_COMMAND_REDO); |
785 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), WEBKIT_EDITING_COMMAND_REDO); |
786 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(editingCommandCallback), window); |
787 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
788 | gtk_widget_show(GTK_WIDGET(item)); |
789 | |
790 | item = gtk_separator_tool_item_new(); |
791 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
792 | gtk_widget_show(GTK_WIDGET(item)); |
793 | |
794 | item = gtk_radio_tool_button_new_from_stock(NULL, GTK_STOCK_JUSTIFY_LEFT); |
795 | GSList *justifyRadioGroup = gtk_radio_tool_button_get_group(GTK_RADIO_TOOL_BUTTON(item)); |
796 | gtk_widget_set_name(GTK_WIDGET(item), "JustifyLeft" ); |
797 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Justify Left" ); |
798 | g_signal_connect(G_OBJECT(item), "toggled" , G_CALLBACK(editingCommandCallback), window); |
799 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
800 | gtk_widget_show(GTK_WIDGET(item)); |
801 | |
802 | item = gtk_radio_tool_button_new_from_stock(justifyRadioGroup, GTK_STOCK_JUSTIFY_CENTER); |
803 | justifyRadioGroup = gtk_radio_tool_button_get_group(GTK_RADIO_TOOL_BUTTON(item)); |
804 | gtk_widget_set_name(GTK_WIDGET(item), "JustifyCenter" ); |
805 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Justify Center" ); |
806 | g_signal_connect(G_OBJECT(item), "toggled" , G_CALLBACK(editingCommandCallback), window); |
807 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
808 | gtk_widget_show(GTK_WIDGET(item)); |
809 | |
810 | item = gtk_radio_tool_button_new_from_stock(justifyRadioGroup, GTK_STOCK_JUSTIFY_RIGHT); |
811 | gtk_widget_set_name(GTK_WIDGET(item), "JustifyRight" ); |
812 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Justify Right" ); |
813 | g_signal_connect(G_OBJECT(item), "toggled" , G_CALLBACK(editingCommandCallback), window); |
814 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
815 | gtk_widget_show(GTK_WIDGET(item)); |
816 | |
817 | item = gtk_separator_tool_item_new(); |
818 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
819 | gtk_widget_show(GTK_WIDGET(item)); |
820 | |
821 | item = gtk_tool_button_new_from_stock(GTK_STOCK_INDENT); |
822 | gtk_widget_set_name(GTK_WIDGET(item), "Indent" ); |
823 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Indent" ); |
824 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(editingCommandCallback), window); |
825 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
826 | gtk_widget_show(GTK_WIDGET(item)); |
827 | |
828 | item = gtk_tool_button_new_from_stock(GTK_STOCK_UNINDENT); |
829 | gtk_widget_set_name(GTK_WIDGET(item), "Outdent" ); |
830 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Outdent" ); |
831 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(editingCommandCallback), window); |
832 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
833 | gtk_widget_show(GTK_WIDGET(item)); |
834 | |
835 | item = gtk_separator_tool_item_new(); |
836 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
837 | gtk_widget_show(GTK_WIDGET(item)); |
838 | |
839 | item = gtk_tool_button_new(NULL, NULL); |
840 | gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item), "insert-image" ); |
841 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Insert Image" ); |
842 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(insertImageCommandCallback), window); |
843 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
844 | gtk_widget_show(GTK_WIDGET(item)); |
845 | |
846 | item = gtk_tool_button_new(NULL, NULL); |
847 | gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(item), "insert-link" ); |
848 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Insert Link" ); |
849 | g_signal_connect(G_OBJECT(item), "clicked" , G_CALLBACK(insertLinkCommandCallback), window); |
850 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
851 | gtk_widget_show(GTK_WIDGET(item)); |
852 | |
853 | gtk_box_pack_start(GTK_BOX(window->mainBox), toolbar, FALSE, FALSE, 0); |
854 | gtk_box_reorder_child(GTK_BOX(window->mainBox), toolbar, 1); |
855 | gtk_widget_show(toolbar); |
856 | } |
857 | |
858 | static void browserWindowSwitchTab(GtkNotebook *notebook, BrowserTab *tab, guint tabIndex, BrowserWindow *window) |
859 | { |
860 | if (window->activeTab == tab) |
861 | return; |
862 | |
863 | if (window->activeTab) { |
864 | browser_tab_set_status_text(window->activeTab, NULL); |
865 | g_clear_object(&window->favicon); |
866 | |
867 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
868 | g_signal_handlers_disconnect_by_data(webView, window); |
869 | |
870 | /* We always want close to be connected even for not active tabs */ |
871 | g_signal_connect(webView, "close" , G_CALLBACK(webViewClose), window); |
872 | |
873 | WebKitBackForwardList *backForwardlist = webkit_web_view_get_back_forward_list(webView); |
874 | g_signal_handlers_disconnect_by_data(backForwardlist, window); |
875 | } |
876 | |
877 | window->activeTab = tab; |
878 | |
879 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
880 | if (webkit_web_view_is_editable(webView)) { |
881 | browserWindowSetupEditorToolbar(window); |
882 | g_signal_connect(webkit_web_view_get_editor_state(webView), "notify::typing-attributes" , G_CALLBACK(typingAttributesChanged), window); |
883 | } |
884 | webViewURIChanged(webView, NULL, window); |
885 | webViewTitleChanged(webView, NULL, window); |
886 | webViewIsLoadingChanged(webView, NULL, window); |
887 | faviconChanged(webView, NULL, window); |
888 | browserWindowUpdateZoomActions(window); |
889 | if (webkit_web_view_is_loading(webView)) |
890 | webViewLoadProgressChanged(webView, NULL, window); |
891 | |
892 | g_signal_connect(webView, "notify::uri" , G_CALLBACK(webViewURIChanged), window); |
893 | g_signal_connect(webView, "notify::estimated-load-progress" , G_CALLBACK(webViewLoadProgressChanged), window); |
894 | g_signal_connect(webView, "notify::title" , G_CALLBACK(webViewTitleChanged), window); |
895 | g_signal_connect(webView, "notify::is-loading" , G_CALLBACK(webViewIsLoadingChanged), window); |
896 | g_signal_connect(webView, "create" , G_CALLBACK(webViewCreate), window); |
897 | g_signal_connect(webView, "close" , G_CALLBACK(webViewClose), window); |
898 | g_signal_connect(webView, "load-failed" , G_CALLBACK(webViewLoadFailed), window); |
899 | g_signal_connect(webView, "decide-policy" , G_CALLBACK(webViewDecidePolicy), window); |
900 | g_signal_connect(webView, "mouse-target-changed" , G_CALLBACK(webViewMouseTargetChanged), window); |
901 | g_signal_connect(webView, "notify::zoom-level" , G_CALLBACK(webViewZoomLevelChanged), window); |
902 | g_signal_connect(webView, "notify::favicon" , G_CALLBACK(faviconChanged), window); |
903 | g_signal_connect(webView, "enter-fullscreen" , G_CALLBACK(webViewEnterFullScreen), window); |
904 | g_signal_connect(webView, "leave-fullscreen" , G_CALLBACK(webViewLeaveFullScreen), window); |
905 | g_signal_connect(webView, "scroll-event" , G_CALLBACK(scrollEventCallback), window); |
906 | |
907 | WebKitBackForwardList *backForwardlist = webkit_web_view_get_back_forward_list(webView); |
908 | browserWindowUpdateNavigationActions(window, backForwardlist); |
909 | g_signal_connect(backForwardlist, "changed" , G_CALLBACK(backForwardlistChanged), window); |
910 | } |
911 | |
912 | static void browserWindowTabAddedOrRemoved(GtkNotebook *notebook, BrowserTab *tab, guint tabIndex, BrowserWindow *window) |
913 | { |
914 | gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window->notebook), gtk_notebook_get_n_pages(notebook) > 1); |
915 | } |
916 | |
917 | static void browser_window_init(BrowserWindow *window) |
918 | { |
919 | windowList = g_list_append(windowList, window); |
920 | |
921 | window->backgroundColor.red = window->backgroundColor.green = window->backgroundColor.blue = 255; |
922 | window->backgroundColor.alpha = 1; |
923 | |
924 | gtk_window_set_title(GTK_WINDOW(window), defaultWindowTitle); |
925 | gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); |
926 | |
927 | window->uriEntry = gtk_entry_new(); |
928 | g_signal_connect_swapped(window->uriEntry, "activate" , G_CALLBACK(activateUriEntryCallback), (gpointer)window); |
929 | gtk_entry_set_icon_activatable(GTK_ENTRY(window->uriEntry), GTK_ENTRY_ICON_PRIMARY, FALSE); |
930 | updateUriEntryIcon(window); |
931 | |
932 | /* Keyboard accelerators */ |
933 | window->accelGroup = gtk_accel_group_new(); |
934 | gtk_window_add_accel_group(GTK_WINDOW(window), window->accelGroup); |
935 | |
936 | /* Global accelerators */ |
937 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_I, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE, |
938 | g_cclosure_new_swap(G_CALLBACK(toggleWebInspector), window, NULL)); |
939 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_F12, 0, GTK_ACCEL_VISIBLE, |
940 | g_cclosure_new_swap(G_CALLBACK(toggleWebInspector), window, NULL)); |
941 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_P, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE, |
942 | g_cclosure_new_swap(G_CALLBACK(openPrivateWindow), window, NULL)); |
943 | |
944 | /* Reload page */ |
945 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_F5, 0, GTK_ACCEL_VISIBLE, |
946 | g_cclosure_new_swap(G_CALLBACK(reloadPage), window, NULL)); |
947 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_R, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
948 | g_cclosure_new_swap(G_CALLBACK(reloadPage), window, NULL)); |
949 | |
950 | /* Reload page ignoring cache */ |
951 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_F5, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
952 | g_cclosure_new_swap(G_CALLBACK(reloadPageIgnoringCache), window, NULL)); |
953 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_R, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE, |
954 | g_cclosure_new_swap(G_CALLBACK(reloadPageIgnoringCache), window, NULL)); |
955 | |
956 | /* Stop page load */ |
957 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_F6, 0, GTK_ACCEL_VISIBLE, |
958 | g_cclosure_new_swap(G_CALLBACK(stopPageLoad), window, NULL)); |
959 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_Escape, 0, GTK_ACCEL_VISIBLE, |
960 | g_cclosure_new_swap(G_CALLBACK(stopPageLoad), window, NULL)); |
961 | |
962 | /* Load home page */ |
963 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_Home, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE, |
964 | g_cclosure_new_swap(G_CALLBACK(loadHomePage), window, NULL)); |
965 | |
966 | /* Zoom in, zoom out and default zoom*/ |
967 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_equal, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
968 | g_cclosure_new_swap(G_CALLBACK(zoomInCallback), window, NULL)); |
969 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_KP_Add, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
970 | g_cclosure_new_swap(G_CALLBACK(zoomInCallback), window, NULL)); |
971 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_minus, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
972 | g_cclosure_new_swap(G_CALLBACK(zoomOutCallback), window, NULL)); |
973 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_KP_Subtract, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
974 | g_cclosure_new_swap(G_CALLBACK(zoomOutCallback), window, NULL)); |
975 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_0, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
976 | g_cclosure_new_swap(G_CALLBACK(defaultZoomCallback), window, NULL)); |
977 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_KP_0, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
978 | g_cclosure_new_swap(G_CALLBACK(defaultZoomCallback), window, NULL)); |
979 | |
980 | /* Toggle fullscreen */ |
981 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_F11, 0, GTK_ACCEL_VISIBLE, |
982 | g_cclosure_new_swap(G_CALLBACK(toggleFullScreen), window, NULL)); |
983 | |
984 | /* Quit */ |
985 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_Q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
986 | g_cclosure_new_swap(G_CALLBACK(browserWindowTryClose), window, NULL)); |
987 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_W, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
988 | g_cclosure_new_swap(G_CALLBACK(browserWindowTryCloseCurrentWebView), window, NULL)); |
989 | |
990 | /* Print */ |
991 | gtk_accel_group_connect(window->accelGroup, GDK_KEY_P, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE, |
992 | g_cclosure_new_swap(G_CALLBACK(printPage), window, NULL)); |
993 | |
994 | GtkWidget *toolbar = gtk_toolbar_new(); |
995 | window->toolbar = toolbar; |
996 | gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL); |
997 | gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH_HORIZ); |
998 | |
999 | GtkToolItem *item = gtk_menu_tool_button_new_from_stock(GTK_STOCK_GO_BACK); |
1000 | window->backItem = GTK_WIDGET(item); |
1001 | gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(item), 0); |
1002 | g_signal_connect_swapped(item, "clicked" , G_CALLBACK(goBackCallback), (gpointer)window); |
1003 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Back" ); |
1004 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1005 | gtk_widget_show(GTK_WIDGET(item)); |
1006 | |
1007 | item = gtk_menu_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD); |
1008 | window->forwardItem = GTK_WIDGET(item); |
1009 | gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(item), 0); |
1010 | g_signal_connect_swapped(G_OBJECT(item), "clicked" , G_CALLBACK(goForwardCallback), (gpointer)window); |
1011 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Forward" ); |
1012 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1013 | gtk_widget_show(GTK_WIDGET(item)); |
1014 | |
1015 | item = gtk_tool_button_new_from_stock(GTK_STOCK_PREFERENCES); |
1016 | g_signal_connect_swapped(G_OBJECT(item), "clicked" , G_CALLBACK(settingsCallback), window); |
1017 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Preferences" ); |
1018 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1019 | gtk_widget_show(GTK_WIDGET(item)); |
1020 | |
1021 | item = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_OUT); |
1022 | window->zoomOutItem = GTK_WIDGET(item); |
1023 | g_signal_connect_swapped(item, "clicked" , G_CALLBACK(zoomOutCallback), window); |
1024 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Zoom Out" ); |
1025 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1026 | gtk_widget_show(GTK_WIDGET(item)); |
1027 | |
1028 | item = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_IN); |
1029 | window->zoomInItem = GTK_WIDGET(item); |
1030 | g_signal_connect_swapped(item, "clicked" , G_CALLBACK(zoomInCallback), window); |
1031 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Zoom In" ); |
1032 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1033 | gtk_widget_show(GTK_WIDGET(item)); |
1034 | |
1035 | item = gtk_tool_button_new_from_stock(GTK_STOCK_FIND); |
1036 | g_signal_connect_swapped(item, "clicked" , G_CALLBACK(searchCallback), window); |
1037 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Find" ); |
1038 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1039 | gtk_widget_add_accelerator(GTK_WIDGET(item), "clicked" , window->accelGroup, GDK_KEY_F, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); |
1040 | gtk_widget_show(GTK_WIDGET(item)); |
1041 | |
1042 | item = gtk_tool_button_new_from_stock(GTK_STOCK_HOME); |
1043 | g_signal_connect_swapped(item, "clicked" , G_CALLBACK(loadHomePage), window); |
1044 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Home" ); |
1045 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1046 | gtk_widget_add_accelerator(GTK_WIDGET(item), "clicked" , window->accelGroup, GDK_KEY_Home, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); |
1047 | gtk_widget_show(GTK_WIDGET(item)); |
1048 | |
1049 | item = gtk_tool_button_new(gtk_image_new_from_icon_name("tab-new" , GTK_ICON_SIZE_SMALL_TOOLBAR), NULL); |
1050 | g_signal_connect_swapped(item, "clicked" , G_CALLBACK(newTabCallback), window); |
1051 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "New Tab" ); |
1052 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1053 | gtk_widget_add_accelerator(GTK_WIDGET(item), "clicked" , window->accelGroup, GDK_KEY_T, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); |
1054 | gtk_widget_show_all(GTK_WIDGET(item)); |
1055 | |
1056 | item = gtk_tool_item_new(); |
1057 | gtk_tool_item_set_expand(item, TRUE); |
1058 | gtk_container_add(GTK_CONTAINER(item), window->uriEntry); |
1059 | gtk_widget_show(window->uriEntry); |
1060 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1061 | gtk_widget_show(GTK_WIDGET(item)); |
1062 | |
1063 | item = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH); |
1064 | window->reloadOrStopButton = GTK_WIDGET(item); |
1065 | g_signal_connect_swapped(item, "clicked" , G_CALLBACK(reloadOrStopCallback), window); |
1066 | gtk_tool_button_set_label(GTK_TOOL_BUTTON(item), "Reload" ); |
1067 | gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1); |
1068 | gtk_widget_add_accelerator(window->reloadOrStopButton, "clicked" , window->accelGroup, GDK_KEY_F5, 0, GTK_ACCEL_VISIBLE); |
1069 | gtk_widget_show(window->reloadOrStopButton); |
1070 | |
1071 | GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); |
1072 | window->mainBox = vbox; |
1073 | gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0); |
1074 | gtk_widget_show(toolbar); |
1075 | |
1076 | window->notebook = gtk_notebook_new(); |
1077 | g_signal_connect(window->notebook, "switch-page" , G_CALLBACK(browserWindowSwitchTab), window); |
1078 | g_signal_connect(window->notebook, "page-added" , G_CALLBACK(browserWindowTabAddedOrRemoved), window); |
1079 | g_signal_connect(window->notebook, "page-removed" , G_CALLBACK(browserWindowTabAddedOrRemoved), window); |
1080 | gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window->notebook), FALSE); |
1081 | gtk_notebook_set_show_border(GTK_NOTEBOOK(window->notebook), FALSE); |
1082 | gtk_box_pack_start(GTK_BOX(window->mainBox), window->notebook, TRUE, TRUE, 0); |
1083 | gtk_widget_show(window->notebook); |
1084 | |
1085 | gtk_container_add(GTK_CONTAINER(window), vbox); |
1086 | gtk_widget_show(vbox); |
1087 | } |
1088 | |
1089 | static void browserWindowConstructed(GObject *gObject) |
1090 | { |
1091 | G_OBJECT_CLASS(browser_window_parent_class)->constructed(gObject); |
1092 | } |
1093 | |
1094 | static void browserWindowSaveSession(BrowserWindow *window) |
1095 | { |
1096 | if (!window->sessionFile) |
1097 | return; |
1098 | |
1099 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
1100 | WebKitWebViewSessionState *state = webkit_web_view_get_session_state(webView); |
1101 | GBytes *bytes = webkit_web_view_session_state_serialize(state); |
1102 | webkit_web_view_session_state_unref(state); |
1103 | g_file_set_contents(window->sessionFile, g_bytes_get_data(bytes, NULL), g_bytes_get_size(bytes), NULL); |
1104 | g_bytes_unref(bytes); |
1105 | } |
1106 | |
1107 | static gboolean browserWindowDeleteEvent(GtkWidget *widget, GdkEventAny* event) |
1108 | { |
1109 | BrowserWindow *window = BROWSER_WINDOW(widget); |
1110 | browserWindowSaveSession(window); |
1111 | browserWindowTryClose(window); |
1112 | return TRUE; |
1113 | } |
1114 | |
1115 | static void browser_window_class_init(BrowserWindowClass *klass) |
1116 | { |
1117 | GObjectClass *gobjectClass = G_OBJECT_CLASS(klass); |
1118 | |
1119 | gobjectClass->constructed = browserWindowConstructed; |
1120 | gobjectClass->finalize = browserWindowFinalize; |
1121 | |
1122 | GtkWidgetClass *widgetClass = GTK_WIDGET_CLASS(klass); |
1123 | widgetClass->delete_event = browserWindowDeleteEvent; |
1124 | } |
1125 | |
1126 | /* Public API. */ |
1127 | GtkWidget *browser_window_new(GtkWindow *parent, WebKitWebContext *webContext) |
1128 | { |
1129 | g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(webContext), NULL); |
1130 | |
1131 | BrowserWindow *window = BROWSER_WINDOW(g_object_new(BROWSER_TYPE_WINDOW, |
1132 | "type" , GTK_WINDOW_TOPLEVEL, NULL)); |
1133 | |
1134 | window->webContext = webContext; |
1135 | g_signal_connect(window->webContext, "download-started" , G_CALLBACK(downloadStarted), window); |
1136 | if (parent) { |
1137 | window->parentWindow = parent; |
1138 | g_object_add_weak_pointer(G_OBJECT(parent), (gpointer *)&window->parentWindow); |
1139 | } |
1140 | |
1141 | return GTK_WIDGET(window); |
1142 | } |
1143 | |
1144 | WebKitWebContext *browser_window_get_web_context(BrowserWindow *window) |
1145 | { |
1146 | g_return_val_if_fail(BROWSER_IS_WINDOW(window), NULL); |
1147 | |
1148 | return window->webContext; |
1149 | } |
1150 | |
1151 | void browser_window_append_view(BrowserWindow *window, WebKitWebView *webView) |
1152 | { |
1153 | g_return_if_fail(BROWSER_IS_WINDOW(window)); |
1154 | g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); |
1155 | |
1156 | if (window->activeTab && webkit_web_view_is_editable(browser_tab_get_web_view(window->activeTab))) { |
1157 | g_warning("Only one tab is allowed in editable mode" ); |
1158 | return; |
1159 | } |
1160 | |
1161 | GtkWidget *tab = browser_tab_new(webView); |
1162 | if (gtk_widget_get_app_paintable(GTK_WIDGET(window))) |
1163 | browser_tab_set_background_color(BROWSER_TAB(tab), &window->backgroundColor); |
1164 | browser_tab_add_accelerators(BROWSER_TAB(tab), window->accelGroup); |
1165 | gtk_notebook_append_page(GTK_NOTEBOOK(window->notebook), tab, browser_tab_get_title_widget(BROWSER_TAB(tab))); |
1166 | gtk_container_child_set(GTK_CONTAINER(window->notebook), tab, "tab-expand" , TRUE, NULL); |
1167 | gtk_widget_show(tab); |
1168 | } |
1169 | |
1170 | void browser_window_load_uri(BrowserWindow *window, const char *uri) |
1171 | { |
1172 | g_return_if_fail(BROWSER_IS_WINDOW(window)); |
1173 | g_return_if_fail(uri); |
1174 | |
1175 | browser_tab_load_uri(window->activeTab, uri); |
1176 | } |
1177 | |
1178 | void browser_window_load_session(BrowserWindow *window, const char *sessionFile) |
1179 | { |
1180 | g_return_if_fail(BROWSER_IS_WINDOW(window)); |
1181 | g_return_if_fail(sessionFile); |
1182 | |
1183 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
1184 | window->sessionFile = g_strdup(sessionFile); |
1185 | gchar *data = NULL; |
1186 | gsize dataLength; |
1187 | if (g_file_get_contents(sessionFile, &data, &dataLength, NULL)) { |
1188 | GBytes *bytes = g_bytes_new_take(data, dataLength); |
1189 | WebKitWebViewSessionState *state = webkit_web_view_session_state_new(bytes); |
1190 | g_bytes_unref(bytes); |
1191 | |
1192 | if (state) { |
1193 | webkit_web_view_restore_session_state(webView, state); |
1194 | webkit_web_view_session_state_unref(state); |
1195 | } |
1196 | } |
1197 | |
1198 | WebKitBackForwardList *bfList = webkit_web_view_get_back_forward_list(webView); |
1199 | WebKitBackForwardListItem *item = webkit_back_forward_list_get_current_item(bfList); |
1200 | if (item) |
1201 | webkit_web_view_go_to_back_forward_list_item(webView, item); |
1202 | else |
1203 | webkit_web_view_load_uri(webView, BROWSER_DEFAULT_URL); |
1204 | |
1205 | } |
1206 | |
1207 | void browser_window_set_background_color(BrowserWindow *window, GdkRGBA *rgba) |
1208 | { |
1209 | g_return_if_fail(BROWSER_IS_WINDOW(window)); |
1210 | g_return_if_fail(rgba); |
1211 | |
1212 | g_assert(!window->activeTab); |
1213 | |
1214 | if (gdk_rgba_equal(rgba, &window->backgroundColor)) |
1215 | return; |
1216 | |
1217 | window->backgroundColor = *rgba; |
1218 | |
1219 | GdkVisual *rgbaVisual = gdk_screen_get_rgba_visual(gtk_window_get_screen(GTK_WINDOW(window))); |
1220 | if (!rgbaVisual) |
1221 | return; |
1222 | |
1223 | gtk_widget_set_visual(GTK_WIDGET(window), rgbaVisual); |
1224 | gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE); |
1225 | } |
1226 | |
1227 | WebKitWebView *browser_window_get_or_create_web_view_for_automation(void) |
1228 | { |
1229 | if (!windowList) |
1230 | return NULL; |
1231 | |
1232 | BrowserWindow *window = (BrowserWindow *)windowList->data; |
1233 | WebKitWebView *webView = browser_tab_get_web_view(window->activeTab); |
1234 | if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(window->notebook)) == 1 && !webkit_web_view_get_uri(webView)) { |
1235 | webkit_web_view_load_uri(webView, "about:blank" ); |
1236 | return webView; |
1237 | } |
1238 | |
1239 | WebKitWebView *newWebView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, |
1240 | "web-context" , webkit_web_view_get_context(webView), |
1241 | "settings" , webkit_web_view_get_settings(webView), |
1242 | "user-content-manager" , webkit_web_view_get_user_content_manager(webView), |
1243 | "is-controlled-by-automation" , TRUE, |
1244 | NULL)); |
1245 | browser_window_append_view(window, newWebView); |
1246 | webkit_web_view_load_uri(newWebView, "about:blank" ); |
1247 | gtk_widget_grab_focus(GTK_WIDGET(newWebView)); |
1248 | return newWebView; |
1249 | } |
1250 | |