NetSurf
window.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 Daniel Silverstone <dsilvers@digital-scurf.org>
3 * Copyright 2006 Rob Kendrick <rjek@rjek.com>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * Implementation of gtk windowing.
23 */
24
25#include <stdlib.h>
26#include <string.h>
27#include <limits.h>
28#include <assert.h>
29#include <math.h>
30#include <gtk/gtk.h>
31#include <gdk/gdkkeysyms.h>
32#include <gdk-pixbuf/gdk-pixdata.h>
33
34#include "utils/utils.h"
35#include "utils/log.h"
36#include "utils/utf8.h"
37#include "utils/nsoption.h"
38#include "utils/messages.h"
39#include "utils/nsurl.h"
40#include "netsurf/inttypes.h"
41#include "netsurf/content.h"
43#include "netsurf/mouse.h"
44#include "netsurf/window.h"
45#include "netsurf/plotters.h"
46#include "netsurf/form.h"
47#include "netsurf/keypress.h"
48#include "desktop/searchweb.h"
49#include "desktop/textinput.h"
50
51#include "gtk/selection.h"
52#include "gtk/warn.h"
53#include "gtk/compat.h"
54#include "gtk/gui.h"
55#include "gtk/scaffolding.h"
56#include "gtk/toolbar_items.h"
57#include "gtk/toolbar.h"
58#include "gtk/local_history.h"
59#include "gtk/plotters.h"
60#include "gtk/schedule.h"
61#include "gtk/tabs.h"
62#include "gtk/bitmap.h"
63#include "gtk/gdk.h"
64#include "gtk/resources.h"
65#include "gtk/search.h"
66#include "gtk/throbber.h"
67#include "gtk/window.h"
68
69/**
70 * time (in ms) between throbber animation frame updates
71 */
72#define THROBBER_FRAME_TIME (100)
73
74static GtkWidget *select_menu;
76
77struct gui_window {
78 /**
79 * The gtk scaffold object containing menu, buttons, url bar, [tabs],
80 * drawing area, etc that may contain one or more gui_windows.
81 */
83
84 /** The 'content' window that is rendered in the gui_window */
85 struct browser_window *bw;
86
87 /** mouse state and events. */
88 struct {
89 struct gui_window *gui;
90
91 gdouble pressed_x;
92 gdouble pressed_y;
93 gboolean waiting;
96
97 /** caret dimension and location for rendering */
98 int caretx, carety, careth;
99
100 /** caret shape for rendering */
102
103 /** previous event location */
104 int last_x, last_y;
105
106 /** controls toolbar context */
108
109 /** search toolbar context */
111
112 /** The top level container (tabBox) */
113 GtkWidget *container;
114
115 /** display widget for this page or frame */
116 GtkLayout *layout;
117
118 /** The container for the layout etc */
119 GtkWidget *grid;
120
121 /** handle to the the visible tab */
122 GtkWidget *tab;
123
124 /** statusbar */
125 GtkLabel *status_bar;
126
127 /** status pane */
128 GtkPaned *paned;
129
130 /** has the status pane had its first size operation yet? */
132
133 /** The icon this window should have */
134 GdkPixbuf *icon;
135
136 /** The input method to use with this window */
137 GtkIMContext *input_method;
138
139 /** current frame of throbber */
141
142 /** list for cleanup */
143 struct gui_window *next, *prev;
144};
145
146/**< first entry in window list */
147struct gui_window *window_list = NULL;
148
149static void
150nsgtk_select_menu_clicked(GtkCheckMenuItem *checkmenuitem,
151 gpointer user_data)
152{
154 (intptr_t)user_data);
155}
156
157#if GTK_CHECK_VERSION(3,0,0)
158
159static gboolean
160nsgtk_window_draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
161{
162 struct gui_window *gw = data;
163 struct gui_window *z;
164 struct rect clip;
165 struct redraw_context ctx = {
166 .interactive = true,
167 .background_images = true,
168 .plot = &nsgtk_plotters
169 };
170
171 double x1;
172 double y1;
173 double x2;
174 double y2;
175
176 assert(gw);
177 assert(gw->bw);
178
179 for (z = window_list; z && z != gw; z = z->next)
180 continue;
181 assert(z);
182 assert(GTK_WIDGET(gw->layout) == widget);
183
184 current_cr = cr;
185
186 GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(gw->layout);
187 GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(gw->layout);
188
189 cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
190
191 clip.x0 = x1;
192 clip.y0 = y1;
193 clip.x1 = x2;
194 clip.y1 = y2;
195
197 -gtk_adjustment_get_value(hscroll),
198 -gtk_adjustment_get_value(vscroll),
199 &clip,
200 &ctx);
201
202 if (gw->careth != 0) {
203 nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth);
204 }
205
206 return FALSE;
207}
208
209#else
210
211static gboolean
212nsgtk_window_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
213{
214 struct gui_window *gw = data;
215 struct gui_window *z;
216 struct rect clip;
217 struct redraw_context ctx = {
218 .interactive = true,
219 .background_images = true,
220 .plot = &nsgtk_plotters
221 };
222
223 assert(gw);
224 assert(gw->bw);
225
226 for (z = window_list; z && z != gw; z = z->next)
227 continue;
228 assert(z);
229 assert(GTK_WIDGET(gw->layout) == widget);
230
231 current_cr = gdk_cairo_create(nsgtk_layout_get_bin_window(gw->layout));
232
233 clip.x0 = event->area.x;
234 clip.y0 = event->area.y;
235 clip.x1 = event->area.x + event->area.width;
236 clip.y1 = event->area.y + event->area.height;
237
238 browser_window_redraw(gw->bw, 0, 0, &clip, &ctx);
239
240 if (gw->careth != 0) {
241 nsgtk_plot_caret(gw->caretx, gw->carety, gw->careth);
242 }
243
244 cairo_destroy(current_cr);
245
246 return FALSE;
247}
248
249#endif
250
251static gboolean
253 GdkEventMotion *event,
254 gpointer data)
255{
256 struct gui_window *g = data;
257 bool shift = event->state & GDK_SHIFT_MASK;
258 bool ctrl = event->state & GDK_CONTROL_MASK;
259
260 if ((fabs(event->x - g->last_x) < 5.0) &&
261 (fabs(event->y - g->last_y) < 5.0)) {
262 /* Mouse hasn't moved far enough from press coordinate
263 * for this to be considered a drag.
264 */
265 return FALSE;
266 } else {
267 /* This is a drag, ensure it's always treated as such,
268 * even if we drag back over the press location.
269 */
270 g->last_x = INT_MIN;
271 g->last_y = INT_MIN;
272 }
273
275 /* Start button 1 drag */
278
279 /* Replace PRESS with HOLDING and declare drag in progress */
283 } else if (g->mouse.state & BROWSER_MOUSE_PRESS_2) {
284 /* Start button 2 drag */
287
288 /* Replace PRESS with HOLDING and declare drag in progress */
292 }
293
294 /* Handle modifiers being removed */
295 if (g->mouse.state & BROWSER_MOUSE_MOD_1 && !shift)
297 if (g->mouse.state & BROWSER_MOUSE_MOD_2 && !ctrl)
299
300 browser_window_mouse_track(g->bw, g->mouse.state, event->x, event->y);
301
302 return TRUE;
303}
304
305/**
306 * GTK signal handler for focus-out-event on layout
307 *
308 * when focus leaves the layout widget ensure the caret is cleared
309 */
310static gboolean
312 GdkEvent *event,
313 gpointer data)
314{
315 struct gui_window *g = data;
316
318 return FALSE;
319}
320
321/**
322 * GTK signal handler for button-press-event on layout
323 */
324static gboolean
326 GdkEventButton *event,
327 gpointer data)
328{
329 struct gui_window *g = data;
330
331 gtk_im_context_reset(g->input_method);
332 gtk_widget_grab_focus(GTK_WIDGET(g->layout));
334
335 g->mouse.pressed_x = event->x;
336 g->mouse.pressed_y = event->y;
337
338 switch (event->button) {
339 case 1: /* Left button, usually. Pass to core as BUTTON 1. */
341 break;
342
343 case 2: /* Middle button, usually. Pass to core as BUTTON 2 */
345 break;
346
347 case 3: /* Right button, usually. Action button, context menu. */
348 /** \todo determine if hiding the caret here is necessary */
351 g->mouse.pressed_x,
352 g->mouse.pressed_y);
353 return TRUE;
354
355 case 8: /* Back button */
357 break;
358
359 case 9: /* Forward button */
361 break;
362
363 default:
364 return FALSE;
365 }
366
367 /* Modify for double & triple clicks */
368 if (event->type == GDK_3BUTTON_PRESS)
370 else if (event->type == GDK_2BUTTON_PRESS)
372
373 /* Handle the modifiers too */
374 if (event->state & GDK_SHIFT_MASK)
376 if (event->state & GDK_CONTROL_MASK)
378 if (event->state & GDK_MOD1_MASK)
380
381 /* Record where we pressed, for use when determining whether to start
382 * a drag in motion notify events. */
383 g->last_x = event->x;
384 g->last_y = event->y;
385
387 g->mouse.state,
388 g->mouse.pressed_x,
389 g->mouse.pressed_y);
390
391 return TRUE;
392}
393
394
395static gboolean
397 GdkEventButton *event,
398 gpointer data)
399{
400 struct gui_window *g = data;
401
402 /* If the mouse state is PRESS then we are waiting for a release to emit
403 * a click event, otherwise just reset the state to nothing */
406 } else if (g->mouse.state & BROWSER_MOUSE_PRESS_2) {
408 } else if (g->mouse.state & BROWSER_MOUSE_PRESS_3) {
410 } else if (g->mouse.state & BROWSER_MOUSE_PRESS_4) {
412 } else if (g->mouse.state & BROWSER_MOUSE_PRESS_5) {
414 }
415
416 /* Handle modifiers being removed */
418 !(event->state & GDK_SHIFT_MASK)) {
420 }
422 !(event->state & GDK_CONTROL_MASK)) {
424 }
426 !(event->state & GDK_MOD1_MASK)) {
428 }
429
435 browser_window_mouse_click(g->bw, g->mouse.state, event->x, event->y);
436 } else {
437 browser_window_mouse_track(g->bw, 0, event->x, event->y);
438 }
439
440 g->mouse.state = 0;
441 return TRUE;
442}
443
444
445static gboolean
447 GdkEventScroll *event,
448 gpointer data)
449{
450 struct gui_window *g = data;
451 double value;
452 double deltax = 0;
453 double deltay = 0;
454 GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout);
455 GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout);
456 GtkAllocation alloc;
457
458 switch (event->direction) {
459 case GDK_SCROLL_LEFT:
460 deltax = -1.0;
461 break;
462
463 case GDK_SCROLL_UP:
464 deltay = -1.0;
465 break;
466
467 case GDK_SCROLL_RIGHT:
468 deltax = 1.0;
469 break;
470
471 case GDK_SCROLL_DOWN:
472 deltay = 1.0;
473 break;
474
475#if GTK_CHECK_VERSION(3,4,0)
476 case GDK_SCROLL_SMOOTH:
477 gdk_event_get_scroll_deltas((GdkEvent *)event, &deltax, &deltay);
478 break;
479#endif
480 default:
481 NSLOG(netsurf, INFO, "Unhandled mouse scroll direction");
482 return TRUE;
483 }
484
487
489 event->x, event->y,
490 deltax, deltay) != true) {
491
492 /* core did not handle event so change adjustments */
493
494 /* Horizontal */
495 if (deltax != 0) {
496 value = gtk_adjustment_get_value(hscroll) + deltax;
497
498 /* @todo consider gtk_widget_get_allocated_width() */
499 nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);
500
501 if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) {
502 value = nsgtk_adjustment_get_upper(hscroll) - alloc.width;
503 }
504 if (value < nsgtk_adjustment_get_lower(hscroll)) {
506 }
507
508 gtk_adjustment_set_value(hscroll, value);
509 }
510
511 /* Vertical */
512 if (deltay != 0) {
513 value = gtk_adjustment_get_value(vscroll) + deltay;
514
515 /* @todo consider gtk_widget_get_allocated_height */
516 nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);
517
518 if (value > (nsgtk_adjustment_get_upper(vscroll) - alloc.height)) {
519 value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;
520 }
521 if (value < nsgtk_adjustment_get_lower(vscroll)) {
523 }
524
525 gtk_adjustment_set_value(vscroll, value);
526 }
527 }
528
529 return TRUE;
530}
531
532
533static gboolean
535 GdkEventKey *event,
536 gpointer data)
537{
538 struct gui_window *g = data;
539 uint32_t nskey;
540
541 if (gtk_im_context_filter_keypress(g->input_method, event))
542 return TRUE;
543
544 nskey = gtk_gui_gdkkey_to_nskey(event);
545
546 if (browser_window_key_press(g->bw, nskey))
547 return TRUE;
548
549 if ((event->state & 0x7) != 0)
550 return TRUE;
551
552 double value;
553 GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout);
554 GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout);
555 GtkAllocation alloc;
556
557 /* @todo consider gtk_widget_get_allocated_width() */
558 nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc);
559
560 switch (event->keyval) {
561
562 case GDK_KEY(Home):
563 case GDK_KEY(KP_Home):
565 gtk_adjustment_set_value(vscroll, value);
566 break;
567
568 case GDK_KEY(End):
569 case GDK_KEY(KP_End):
570 value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;
571
574
575 gtk_adjustment_set_value(vscroll, value);
576 break;
577
578 case GDK_KEY(Left):
579 case GDK_KEY(KP_Left):
580 value = gtk_adjustment_get_value(hscroll) -
582
585
586 gtk_adjustment_set_value(hscroll, value);
587 break;
588
589 case GDK_KEY(Up):
590 case GDK_KEY(KP_Up):
591 value = gtk_adjustment_get_value(vscroll) -
593
596
597 gtk_adjustment_set_value(vscroll, value);
598 break;
599
600 case GDK_KEY(Right):
601 case GDK_KEY(KP_Right):
602 value = gtk_adjustment_get_value(hscroll) +
604
605 if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width)
606 value = nsgtk_adjustment_get_upper(hscroll) - alloc.width;
607
608 gtk_adjustment_set_value(hscroll, value);
609 break;
610
611 case GDK_KEY(Down):
612 case GDK_KEY(KP_Down):
613 value = gtk_adjustment_get_value(vscroll) +
615
616 if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height)
617 value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;
618
619 gtk_adjustment_set_value(vscroll, value);
620 break;
621
622 case GDK_KEY(Page_Up):
623 case GDK_KEY(KP_Page_Up):
624 value = gtk_adjustment_get_value(vscroll) -
626
629
630 gtk_adjustment_set_value(vscroll, value);
631 break;
632
633 case GDK_KEY(Page_Down):
634 case GDK_KEY(KP_Page_Down):
635 value = gtk_adjustment_get_value(vscroll) +
637
638 if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height)
639 value = nsgtk_adjustment_get_upper(vscroll) - alloc.height;
640
641 gtk_adjustment_set_value(vscroll, value);
642 break;
643
644 default:
645 break;
646
647 }
648
649 return TRUE;
650}
651
652
653static gboolean
655 GdkEventKey *event,
656 gpointer data)
657{
658 struct gui_window *g = data;
659
660 return gtk_im_context_filter_keypress(g->input_method, event);
661}
662
663
664static void
666 const gchar *str,
667 gpointer data)
668{
669 struct gui_window *g = data;
670 size_t len = strlen(str), offset = 0;
671
672 while (offset < len) {
673 uint32_t nskey = utf8_to_ucs4(str + offset, len - offset);
674
675 browser_window_key_press(g->bw, nskey);
676
677 offset = utf8_next(str, len, offset);
678 }
679}
680
681
682static gboolean
684 GtkAllocation *allocation,
685 gpointer data)
686{
687 struct gui_window *g = data;
688
690
691 return TRUE;
692}
693
694
695/**
696 * when the pane position is changed update the user option
697 *
698 * The slightly awkward implementation with the first allocation flag
699 * is necessary because the initial window creation does not cause an
700 * allocate-event signal so the position value in the pane is incorrect
701 * and we cannot know what it should be until after the allocation
702 * (which did not generate a signal) is done as the user position is a
703 * percentage of pane total width not an absolute value.
704 */
705static void
706nsgtk_paned_notify__position(GObject *gobject, GParamSpec *pspec, gpointer data)
707{
708 struct gui_window *g = data;
709 GtkAllocation pane_alloc;
710
711 gtk_widget_get_allocation(GTK_WIDGET(g->paned), &pane_alloc);
712
713 if (g->paned_sized == false)
714 {
715 g->paned_sized = true;
716 gtk_paned_set_position(g->paned,
717 (nsoption_int(toolbar_status_size) * pane_alloc.width) / 10000);
718 return;
719 }
720
721 nsoption_set_int(toolbar_status_size,
722 ((gtk_paned_get_position(g->paned) * 10000) / (pane_alloc.width - 1)));
723}
724
725
726/**
727 * Set status bar / scroll bar proportion according to user option
728 * when pane is resized.
729 */
730static gboolean
732 GtkAllocation *allocation,
733 gpointer data)
734{
735 gtk_paned_set_position(GTK_PANED(widget),
736 (nsoption_int(toolbar_status_size) * allocation->width) / 10000);
737
738 return TRUE;
739}
740
741
742/**
743 * handler for gtk destroy signal on window container
744 *
745 * destroy the browsing context as there is will be nothing to display it now
746 */
747static void window_destroy(GtkWidget *widget, gpointer data)
748{
749 struct gui_window *gw = data;
750
752
753 g_object_unref(gw->input_method);
754
755 /* free any existing icon */
756 if (gw->icon != NULL) {
757 g_object_unref(gw->icon);
758 gw->icon = NULL;
759 }
760
761 free(gw);
762}
763
764
765static struct browser_window *bw_from_gw(void *data)
766{
767 struct gui_window *gw = data;
768 return gw->bw;
769}
770
771
772static bool get_tool_bar_show(void)
773{
774 const char *cur_bar_show;
775
776 cur_bar_show = nsoption_charp(bar_show);
777 if (cur_bar_show != NULL) {
778 if (strcmp(cur_bar_show, "menu/tool") == 0) {
779 return true;
780 } else if (strcmp(cur_bar_show, "tool") == 0) {
781 return true;
782 }
783 }
784 return false;
785}
786
787
788/**
789 * Make the throbber advance to next frame.
790 *
791 * scheduled callback to update the throbber
792 *
793 * \param p The context passed when scheduled.
794 */
795static void next_throbber_frame(void *p)
796{
797 struct gui_window *gw = p;
798 nserror res;
799 GdkPixbuf *pixbuf;
800
801 gw->throb_frame++; /* advance to next frame */
802
803 res = nsgtk_throbber_get_frame(gw->throb_frame, &pixbuf);
804 if (res == NSERROR_BAD_SIZE) {
805 gw->throb_frame = 1;
806 res = nsgtk_throbber_get_frame(gw->throb_frame, &pixbuf);
807 }
808
809 if (res == NSERROR_OK) {
810 nsgtk_tab_set_icon(gw->container, pixbuf);
811 /* only schedule next frame if there are no errors */
813 }
814}
815
816
817/**
818 * Create and open a gtk container (window or tab) for a browsing context.
819 *
820 * \param bw The browsing context to create gui_window for.
821 * \param existing An existing gui_window, may be NULL
822 * \param flags flags to control the container creation
823 * \return gui window, or NULL on error
824 *
825 * If GW_CREATE_CLONE flag is set existing is non-NULL.
826 *
827 * Front end's gui_window must include a reference to the
828 * browser window passed in the bw param.
829 */
830static struct gui_window *
832 struct gui_window *existing,
834{
835 struct gui_window *g; /* what is being created to return */
836 bool open_in_background = !(nsoption_bool(focus_new));
837 GtkBuilder* tab_builder;
838
839 /* If there is a foreground request, override user preference */
840 if (flags & GW_CREATE_FOREGROUND)
841 open_in_background = false;
842
843 nserror res;
844
845 res = nsgtk_builder_new_from_resname("tabcontents", &tab_builder);
846 if (res != NSERROR_OK) {
847 NSLOG(netsurf, INFO, "Tab contents UI builder init failed");
848 return NULL;
849 }
850
851 gtk_builder_connect_signals(tab_builder, NULL);
852
853 g = calloc(1, sizeof(*g));
854 if (!g) {
855 nsgtk_warning("NoMemory", 0);
856 g_object_unref(tab_builder);
857 return NULL;
858 }
859
860 NSLOG(netsurf, INFO, "Creating gui window %p for browser window %p",
861 g, bw);
862
863 g->bw = bw;
864 g->mouse.state = 0;
866
867 /* attach scaffold */
868 if (flags & GW_CREATE_TAB) {
869 /* open in new tab, attach to existing scaffold */
870 if (existing != NULL) {
871 g->scaffold = existing->scaffold;
872 } else {
874 }
875 } else {
876 /* open in new window, create and attach to scaffold */
878 }
879 if (g->scaffold == NULL) {
880 nsgtk_warning("NoMemory", 0);
881 free(g);
882 g_object_unref(tab_builder);
883 return NULL;
884 }
885
886 /* Construct our primary elements */
887 g->container = GTK_WIDGET(gtk_builder_get_object(tab_builder, "tabBox"));
888 g->layout = GTK_LAYOUT(gtk_builder_get_object(tab_builder, "layout"));
889 g->grid = GTK_WIDGET(gtk_builder_get_object(tab_builder, "tabContents"));
890 g->status_bar = GTK_LABEL(gtk_builder_get_object(tab_builder, "status_bar"));
891 g->paned = GTK_PANED(gtk_builder_get_object(tab_builder, "hpaned1"));
892 g->input_method = gtk_im_multicontext_new();
893
894
895 /* create toolbar */
896 res = nsgtk_toolbar_create(tab_builder, bw_from_gw, g,
897 !!(flags & GW_CREATE_FOCUS_LOCATION),
898 &g->toolbar);
899 if (res != NSERROR_OK) {
900 free(g);
901 g_object_unref(tab_builder);
902 return NULL;
903 }
904
905 /* local page text search toolbar */
906 res = nsgtk_search_create(tab_builder, g->bw, &g->search);
907 if (res != NSERROR_OK) {
908 free(g);
909 g_object_unref(tab_builder);
910 return NULL;
911 }
912
913 /* set a default favicon */
914 g_object_ref(favicon_pixbuf);
915 g->icon = favicon_pixbuf;
916
917 /* add new gui window to global list (push_top) */
918 if (window_list) {
919 window_list->prev = g;
920 }
921 g->next = window_list;
922 g->prev = NULL;
923 window_list = g;
924
925 /* set the events we're interested in receiving from the browser's
926 * drawing area.
927 */
928 gtk_widget_add_events(GTK_WIDGET(g->layout),
929 GDK_EXPOSURE_MASK |
930 GDK_LEAVE_NOTIFY_MASK |
931 GDK_BUTTON_PRESS_MASK |
932 GDK_BUTTON_RELEASE_MASK |
933 GDK_POINTER_MOTION_MASK |
934 GDK_POINTER_MOTION_HINT_MASK |
935 GDK_KEY_PRESS_MASK |
936 GDK_KEY_RELEASE_MASK |
937 GDK_SCROLL_MASK);
938 nsgtk_widget_set_can_focus(GTK_WIDGET(g->layout), TRUE);
939
940 /* set the default background colour of the drawing area to white. */
943 0, 0xffff, 0xffff, 0xffff);
944
945 nsgtk_connect_draw_event(GTK_WIDGET(g->layout),
946 G_CALLBACK(nsgtk_window_draw_event), g);
947
948 /* helper macro to conect signals to callbacks */
949#define CONNECT(obj, sig, callback, ptr) \
950 g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
951
952 /* layout signals */
953 CONNECT(g->layout, "motion-notify-event",
955 CONNECT(g->layout, "button-press-event",
957 CONNECT(g->layout, "button-release-event",
959 CONNECT(g->layout, "key-press-event",
961 CONNECT(g->layout, "key-release-event",
963 CONNECT(g->layout, "size-allocate",
965 CONNECT(g->layout, "scroll-event",
967 CONNECT(g->layout, "focus-out-event",
969
970 /* status pane signals */
971 CONNECT(g->paned, "size-allocate",
973
974 CONNECT(g->paned, "notify::position",
976
977 /* gtk container destructor */
978 CONNECT(g->container, "destroy", window_destroy, g);
979
980 /* input method */
981 gtk_im_context_set_client_window(g->input_method,
983 gtk_im_context_set_use_preedit(g->input_method, FALSE);
984
985 /* input method signals */
986 CONNECT(g->input_method, "commit",
988
989 /* add the tab container to the scaffold notebook */
991 open_in_background,
992 messages_get("NewTab"), g->icon);
993
994 /* initialy should not be visible */
996
997 /* set toolbar visibility from user option */
999
1000 /* safe to drop the reference to the tab_builder as the container is
1001 * referenced by the notebook now.
1002 */
1003 g_object_unref(tab_builder);
1004
1005 /* Finally we need to focus the location bar if requested */
1006 if (flags & GW_CREATE_FOCUS_LOCATION) {
1008 NSLOG(netsurf, WARNING, "Unable to focus location input");
1009 }
1010 }
1011
1012 return g;
1013}
1014
1015
1016static void gui_window_destroy(struct gui_window *gw)
1017{
1018 NSLOG(netsurf, INFO, "gui_window: %p", gw);
1019 assert(gw != NULL);
1020 assert(gw->bw != NULL);
1021 NSLOG(netsurf, INFO, "scaffolding: %p", gw->scaffold);
1022
1023 /* kill off any throbber that might be running */
1025
1026 /* remove from window list */
1027 if (gw->prev) {
1028 gw->prev->next = gw->next;
1029 } else {
1030 window_list = gw->next;
1031 }
1032
1033 if (gw->next) {
1034 gw->next->prev = gw->prev;
1035 }
1036
1037 NSLOG(netsurf, INFO, "window list head: %p", window_list);
1038}
1039
1040
1041/**
1042 * favicon setting for gtk gui window.
1043 *
1044 * \param gw gtk gui window to set favicon on.
1045 * \param icon A handle to the new favicon content.
1046 */
1047static void
1049{
1050 struct bitmap *icon_bitmap = NULL;
1051
1052 /* free any existing icon */
1053 if (gw->icon != NULL) {
1054 g_object_unref(gw->icon);
1055 gw->icon = NULL;
1056 }
1057
1058 if (icon != NULL) {
1059 icon_bitmap = content_get_bitmap(icon);
1060 if (icon_bitmap != NULL) {
1061 NSLOG(netsurf, INFO, "Using %p bitmap", icon_bitmap);
1062 gw->icon = nsgdk_pixbuf_get_from_surface(icon_bitmap->surface, 16, 16);
1063 }
1064 }
1065
1066 if (gw->icon == NULL) {
1067 NSLOG(netsurf, INFO, "Using default favicon");
1068 g_object_ref(favicon_pixbuf);
1069 gw->icon = favicon_pixbuf;
1070 }
1071
1072 /* only set icon if throbber not running */
1073 if (gw->throb_frame == 0) {
1075 }
1076}
1077
1078
1079static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
1080{
1081 GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout);
1082 GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout);
1083
1084 assert(vadj);
1085 assert(hadj);
1086
1087 *sy = (int)(gtk_adjustment_get_value(vadj));
1088 *sx = (int)(gtk_adjustment_get_value(hadj));
1089
1090 return true;
1091}
1092
1093
1094static void nsgtk_redraw_caret(struct gui_window *g)
1095{
1096 int sx, sy;
1097
1098 if (g->careth == 0)
1099 return;
1100
1101 gui_window_get_scroll(g, &sx, &sy);
1102
1103 gtk_widget_queue_draw_area(GTK_WIDGET(g->layout),
1104 g->caretx - sx, g->carety - sy, 1, g->careth + 1);
1105
1106}
1107
1108
1110{
1111 int sx, sy;
1112 int oh = g->careth;
1113
1114 if (oh == 0)
1115 return;
1116
1117 g->careth = 0;
1118
1119 gui_window_get_scroll(g, &sx, &sy);
1120
1121 gtk_widget_queue_draw_area(GTK_WIDGET(g->layout),
1122 g->caretx - sx, g->carety - sy, 1, oh + 1);
1123
1124}
1125
1126
1127/**
1128 * Invalidates an area of a GTK browser window
1129 *
1130 * \param g gui_window
1131 * \param rect area to redraw or NULL for the entire window area
1132 * \return NSERROR_OK on success or appropriate error code
1133 */
1134static nserror
1136{
1137 int sx, sy;
1138
1139 if (rect == NULL) {
1140 gtk_widget_queue_draw(GTK_WIDGET(g->layout));
1141 return NSERROR_OK;
1142 }
1143
1144 if (!browser_window_has_content(g->bw)) {
1145 return NSERROR_OK;
1146 }
1147
1148 gui_window_get_scroll(g, &sx, &sy);
1149
1150 gtk_widget_queue_draw_area(GTK_WIDGET(g->layout),
1151 rect->x0 - sx,
1152 rect->y0 - sy,
1153 rect->x1 - rect->x0,
1154 rect->y1 - rect->y0);
1155
1156 return NSERROR_OK;
1157}
1158
1159
1160static void gui_window_set_status(struct gui_window *g, const char *text)
1161{
1162 assert(g);
1163 assert(g->status_bar);
1164 gtk_label_set_text(g->status_bar, text);
1165}
1166
1167
1168/**
1169 * Set the scroll position of a gtk browser window.
1170 *
1171 * Scrolls the viewport to ensure the specified rectangle of the
1172 * content is shown. The GTK implementation scrolls the contents so
1173 * the specified point in the content is at the top of the viewport.
1174 *
1175 * \param g gui window to scroll
1176 * \param rect The rectangle to ensure is shown.
1177 * \return NSERROR_OK on success or apropriate error code.
1178 */
1179static nserror
1181{
1182 GtkAdjustment *vadj = nsgtk_layout_get_vadjustment(g->layout);
1183 GtkAdjustment *hadj = nsgtk_layout_get_hadjustment(g->layout);
1184 gdouble vlower, vpage, vupper, hlower, hpage, hupper;
1185 gdouble x = (gdouble)rect->x0;
1186 gdouble y = (gdouble)rect->y0;
1187
1188 assert(vadj);
1189 assert(hadj);
1190
1191 g_object_get(vadj, "page-size", &vpage, "lower", &vlower, "upper", &vupper, NULL);
1192 g_object_get(hadj, "page-size", &hpage, "lower", &hlower, "upper", &hupper, NULL);
1193
1194 if (x < hlower) {
1195 x = hlower;
1196 }
1197 if (x > (hupper - hpage)) {
1198 x = hupper - hpage;
1199 }
1200 if (y < vlower) {
1201 y = vlower;
1202 }
1203 if (y > (vupper - vpage)) {
1204 y = vupper - vpage;
1205 }
1206
1207 gtk_adjustment_set_value(vadj, y);
1208 gtk_adjustment_set_value(hadj, x);
1209
1210 return NSERROR_OK;
1211}
1212
1213
1215{
1216 int w, h;
1217
1218 if (browser_window_get_extents(g->bw, true, &w, &h) == NSERROR_OK) {
1219 gtk_layout_set_size(g->layout, w, h);
1220 gtk_widget_queue_resize(g->grid);
1221 }
1222}
1223
1224
1225static void
1227{
1228 GdkCursor *cursor = NULL;
1229 GdkCursorType cursortype;
1230 bool nullcursor = false;
1231
1232 if (g->current_pointer == shape)
1233 return;
1234
1235 g->current_pointer = shape;
1236
1237 switch (shape) {
1238 case GUI_POINTER_POINT:
1239 cursortype = GDK_HAND2;
1240 break;
1241 case GUI_POINTER_CARET:
1242 cursortype = GDK_XTERM;
1243 break;
1244 case GUI_POINTER_UP:
1245 cursortype = GDK_TOP_SIDE;
1246 break;
1247 case GUI_POINTER_DOWN:
1248 cursortype = GDK_BOTTOM_SIDE;
1249 break;
1250 case GUI_POINTER_LEFT:
1251 cursortype = GDK_LEFT_SIDE;
1252 break;
1253 case GUI_POINTER_RIGHT:
1254 cursortype = GDK_RIGHT_SIDE;
1255 break;
1256 case GUI_POINTER_LD:
1257 cursortype = GDK_BOTTOM_LEFT_CORNER;
1258 break;
1259 case GUI_POINTER_RD:
1260 cursortype = GDK_BOTTOM_RIGHT_CORNER;
1261 break;
1262 case GUI_POINTER_LU:
1263 cursortype = GDK_TOP_LEFT_CORNER;
1264 break;
1265 case GUI_POINTER_RU:
1266 cursortype = GDK_TOP_RIGHT_CORNER;
1267 break;
1268 case GUI_POINTER_CROSS:
1269 cursortype = GDK_CROSS;
1270 break;
1271 case GUI_POINTER_MOVE:
1272 cursortype = GDK_FLEUR;
1273 break;
1274 case GUI_POINTER_WAIT:
1275 cursortype = GDK_WATCH;
1276 break;
1277 case GUI_POINTER_HELP:
1278 cursortype = GDK_QUESTION_ARROW;
1279 break;
1280 case GUI_POINTER_MENU:
1281 cursor = nsgtk_create_menu_cursor();
1282 nullcursor = true;
1283 break;
1285 /* In reality, this needs to be the funky left_ptr_watch
1286 * which we can't do easily yet.
1287 */
1288 cursortype = GDK_WATCH;
1289 break;
1290 /* The following we're not sure about */
1294 default:
1295 nullcursor = true;
1296 }
1297
1298 if (!nullcursor)
1299 cursor = gdk_cursor_new_for_display(
1300 gtk_widget_get_display(
1301 GTK_WIDGET(g->layout)),
1302 cursortype);
1303 gdk_window_set_cursor(nsgtk_widget_get_window(GTK_WIDGET(g->layout)),
1304 cursor);
1305
1306 if (!nullcursor)
1307 nsgdk_cursor_unref(cursor);
1308}
1309
1310
1311static void
1313 int x, int y, int height,
1314 const struct rect *clip)
1315{
1317
1318 y += 1;
1319 height -= 1;
1320
1321 if (y < clip->y0) {
1322 height -= clip->y0 - y;
1323 y = clip->y0;
1324 }
1325
1326 if (y + height > clip->y1) {
1327 height = clip->y1 - y + 1;
1328 }
1329
1330 g->caretx = x;
1331 g->carety = y;
1332 g->careth = height;
1333
1335
1336 gtk_widget_grab_focus(GTK_WIDGET(g->layout));
1337}
1338
1339
1340/**
1341 * Find the current dimensions of a GTK browser window content area.
1342 *
1343 * \param gw The gui window to measure content area of.
1344 * \param width receives width of window
1345 * \param height receives height of window
1346 * \return NSERROR_OK on sucess and width and height updated
1347 * else error code.
1348 */
1349static nserror
1351{
1352 GtkAllocation alloc;
1353
1354 /** @todo consider gtk_widget_get_allocated_width() */
1355 nsgtk_widget_get_allocation(GTK_WIDGET(gw->layout), &alloc);
1356
1357 *width = alloc.width;
1358 *height = alloc.height;
1359
1360 return NSERROR_OK;
1361}
1362
1363
1365{
1366 gtk_widget_grab_focus(GTK_WIDGET(g->layout));
1367}
1368
1369
1370static void
1372 struct form_control *control)
1373{
1374 intptr_t item;
1375 struct form_option *option;
1376
1377 GtkWidget *menu_item;
1378
1379 /* control->data.select.multiple is true if multiple selections
1380 * are allowable. We ignore this, as the core handles it for us.
1381 * Yay. \o/
1382 */
1383
1384 if (select_menu != NULL) {
1385 gtk_widget_destroy(select_menu);
1386 }
1387
1388 select_menu = gtk_menu_new();
1389 select_menu_control = control;
1390
1391 item = 0;
1392 option = form_select_get_option(control, item);
1393 while (option != NULL) {
1394 NSLOG(netsurf, INFO, "Item %"PRIdPTR" option %p text %s",
1395 item, option, option->text);
1396 menu_item = gtk_check_menu_item_new_with_label(option->text);
1397 if (option->selected) {
1398 gtk_check_menu_item_set_active(
1399 GTK_CHECK_MENU_ITEM(menu_item), TRUE);
1400 }
1401
1402 /*
1403 * This casts the item index integer into an integer
1404 * the size of a pointer. This allows the callback
1405 * parameter to be passed avoiding allocating memory
1406 * for a context with a single integer in it.
1407 */
1408 g_signal_connect(menu_item, "toggled",
1409 G_CALLBACK(nsgtk_select_menu_clicked), (gpointer)item);
1410
1411 gtk_menu_shell_append(GTK_MENU_SHELL(select_menu), menu_item);
1412
1413 item++;
1414 option = form_select_get_option(control, item);
1415 }
1416
1417 gtk_widget_show_all(select_menu);
1418
1420}
1421
1422
1423/**
1424 * GTK window UI callback when core needs a file selection gadget
1425 *
1426 * \param g The gui window on which the gadget has been requested
1427 */
1428static void
1430 struct hlcache_handle *hl,
1431 struct form_control *gadget)
1432{
1433 GtkWidget *dialog;
1434
1435 dialog = gtk_file_chooser_dialog_new("Select File",
1437 GTK_FILE_CHOOSER_ACTION_OPEN,
1438 NSGTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1439 NSGTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1440 NULL);
1441
1442 NSLOG(netsurf, INFO, "*** open dialog: %p", dialog);
1443
1444 int ret = gtk_dialog_run(GTK_DIALOG(dialog));
1445 NSLOG(netsurf, INFO, "*** return value: %d", ret);
1446 if (ret == GTK_RESPONSE_ACCEPT) {
1447 char *filename;
1448
1449 filename = gtk_file_chooser_get_filename(
1450 GTK_FILE_CHOOSER(dialog));
1451
1452 browser_window_set_gadget_filename(g->bw, gadget, filename);
1453
1454 g_free(filename);
1455 }
1456
1457 gtk_widget_destroy(dialog);
1458}
1459
1460
1461/**
1462 * handle throbber changing state
1463 */
1464static nserror throbber(struct gui_window *gw, bool active)
1465{
1466 nsgtk_toolbar_throbber(gw->toolbar, active);
1467 nsgtk_scaffolding_throbber(gw, active);
1468 if (active) {
1470 } else {
1472 gw->throb_frame = 0;
1473 /* set tab back to favicon */
1475 }
1476 return NSERROR_OK;
1477}
1478
1479
1480/**
1481 * handle page info changing
1482 */
1484{
1486 return NSERROR_OK;
1487}
1488
1489/**
1490 * GTK window UI callback to process miscellaneous events
1491 *
1492 * \param gw The window receiving the event.
1493 * \param event The event code.
1494 * \return NSERROR_OK when processed ok
1495 */
1496static nserror
1498{
1499 switch (event) {
1502 break;
1503
1506 break;
1507
1510 break;
1511
1513 throbber(gw, true);
1514 break;
1515
1517 throbber(gw, false);
1518 break;
1519
1521 page_info_change(gw);
1522 break;
1523
1524 default:
1525 break;
1526 }
1527 return NSERROR_OK;
1528}
1529
1530
1531/**
1532 * GTK window UI callback when core changes the current url
1533 *
1534 * \param gw The gui window on which the url has been set.
1535 * \param url The new url.
1536 */
1538{
1539 return nsgtk_toolbar_set_url(gw->toolbar, url);
1540}
1541
1542
1543/**
1544 * GTK window UI callback when core changes the current title
1545 *
1546 * \param gw The gui window on which the url has been set.
1547 * \param url The new url.
1548 */
1549static void gui_window_set_title(struct gui_window *gw, const char *title)
1550{
1551
1552 if ((title != NULL) && (title[0] != '\0')) {
1553 nsgtk_tab_set_title(gw->container, title);
1554 }
1555 nsgtk_scaffolding_set_title(gw, title);
1556}
1557
1558
1559/**
1560 * GTK UI callback when search provider details are updated.
1561 *
1562 * \param name The providers name.
1563 * \param bitmap The bitmap representing the provider.
1564 * \return NSERROR_OK on success else error code.
1565 */
1566static nserror
1568{
1569 struct gui_window *gw;
1570 GdkPixbuf *pixbuf = NULL;
1571
1572 if (bitmap != NULL) {
1573 pixbuf = nsgdk_pixbuf_get_from_surface(bitmap->surface, 32, 32);
1574 }
1575
1576 for (gw = window_list; gw != NULL; gw = gw->next) {
1578 }
1579
1580 if (pixbuf != NULL) {
1581 g_object_unref(pixbuf);
1582 }
1583
1584 return NSERROR_OK;
1585}
1586
1587
1588/**
1589 * GTK frontend web search operation table
1590 */
1593};
1594
1596
1597
1598/**
1599 * GTK frontend browser window operation table
1600 */
1603 .destroy = gui_window_destroy,
1604 .invalidate = nsgtk_window_invalidate_area,
1605 .get_scroll = gui_window_get_scroll,
1606 .set_scroll = gui_window_set_scroll,
1607 .get_dimensions = gui_window_get_dimensions,
1608 .event = gui_window_event,
1609
1610 .set_icon = gui_window_set_icon,
1611 .set_title = gui_window_set_title,
1612 .set_status = gui_window_set_status,
1613 .set_pointer = gui_window_set_pointer,
1614 .place_caret = gui_window_place_caret,
1615 .create_form_select_menu = gui_window_create_form_select_menu,
1616 .file_gadget_open = gui_window_file_gadget_open,
1617 .set_url = gui_window_set_url,
1618
1619
1620};
1621
1623
1624
1625/* exported interface documented in window.h */
1627{
1628 return g->scaffold;
1629}
1630
1631
1632/* exported interface documented in window.h */
1634{
1635 return g->bw;
1636}
1637
1638
1639/* exported interface documented in window.h */
1641{
1642 return g->layout;
1643}
1644
1645
1646/* exported interface documented in window.h */
1647nserror
1649{
1651}
1652
1653
1654/* exported interface documented in window.h */
1655nserror
1657{
1658 return nsgtk_toolbar_item_activate(gw->toolbar, itemid);
1659}
1660
1661
1662/* exported interface documented in window.h */
1664{
1665 /* remove tab */
1666 gtk_widget_destroy(gw->container);
1667}
1668
1669
1670/* exported interface documented in window.h */
1672{
1673 struct gui_window *gw;
1674 for (gw = window_list; gw != NULL; gw = gw->next) {
1679 }
1680 return NSERROR_OK;
1681}
1682
1683
1684/* exported interface documented in window.h */
1686{
1687 struct gui_window *gw;
1688 for (gw = window_list; gw != NULL; gw = gw->next) {
1689 if (gw->scaffold == gs) {
1690 nsgtk_toolbar_show(gw->toolbar, show);
1691 }
1692 }
1693 return NSERROR_OK;
1694}
1695
1696
1697/* exported interface documented in window.h */
1699{
1700 struct gui_window *gw;
1701 for (gw = window_list; gw != NULL; gw = gw->next) {
1703
1704 }
1705 return NSERROR_OK;
1706}
1707
1708/* exported interface documented in window.h */
1710 struct nsgtk_pi_window *win)
1711{
1713}
1714
1715/* exported interface documented in window.h */
1717{
1719}
Browser window creation and manipulation interface.
nserror browser_window_schedule_reformat(struct browser_window *bw)
Reformat the browser window contents in a safe context.
bool browser_window_redraw(struct browser_window *bw, int x, int y, const struct rect *clip, const struct redraw_context *ctx)
Redraw an area of a window.
bool browser_window_has_content(struct browser_window *bw)
Find out if a browser window is currently showing a content.
void browser_window_mouse_click(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle mouse clicks in a browser window.
bool browser_window_scroll_at_point(struct browser_window *bw, int x, int y, int scrx, int scry)
Send a scroll request to a browser window at a particular point.
void browser_window_destroy(struct browser_window *bw)
Close and destroy a browser window.
nserror browser_window_get_extents(struct browser_window *bw, bool scaled, int *width, int *height)
Get a browser window's content extents.
void browser_window_mouse_track(struct browser_window *bw, browser_mouse_state mouse, int x, int y)
Handle non-click mouse action in a browser window.
void browser_window_set_gadget_filename(struct browser_window *bw, struct form_control *gadget, const char *fn)
set filename on form control.
void nsgtk_widget_get_allocation(GtkWidget *widget, GtkAllocation *allocation)
Definition: compat.c:489
void nsgtk_widget_override_background_color(GtkWidget *widget, GtkStateFlags state, uint16_t a, uint16_t r, uint16_t g, uint16_t b)
Definition: compat.c:240
GdkWindow * nsgtk_widget_get_window(GtkWidget *widget)
Definition: compat.c:404
gulong nsgtk_connect_draw_event(GtkWidget *widget, GCallback callback, gpointer g)
Definition: compat.c:373
void nsgdk_cursor_unref(GdkCursor *cursor)
Definition: compat.c:384
gdouble nsgtk_adjustment_get_page_increment(GtkAdjustment *adjustment)
Definition: compat.c:480
void nsgtk_widget_set_can_focus(GtkWidget *widget, gboolean can_focus)
Definition: compat.c:48
gdouble nsgtk_adjustment_get_upper(GtkAdjustment *adjustment)
Definition: compat.c:462
gdouble nsgtk_adjustment_get_lower(GtkAdjustment *adjustment)
Definition: compat.c:471
GtkAdjustment * nsgtk_layout_get_vadjustment(GtkLayout *layout)
Definition: compat.c:269
GtkAdjustment * nsgtk_layout_get_hadjustment(GtkLayout *layout)
Definition: compat.c:278
GdkWindow * nsgtk_layout_get_bin_window(GtkLayout *layout)
Definition: compat.c:444
gdouble nsgtk_adjustment_get_step_increment(GtkAdjustment *adjustment)
Definition: compat.c:453
void nsgtk_menu_popup_at_pointer(GtkMenu *menu, const GdkEvent *trigger_event)
Displays menu and makes it available for selection.
Definition: compat.c:561
Compatibility functions for older GTK versions (interface)
#define GDK_KEY(symbol)
Definition: compat.h:152
#define NSGTK_STOCK_OPEN
Definition: compat.h:65
#define GTK_STATE_FLAG_NORMAL
Definition: compat.h:160
#define NSGTK_STOCK_CANCEL
Definition: compat.h:55
wimp_w dialog
Definition: dialog.c:87
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_BAD_SIZE
Bad size.
Definition: errors.h:60
@ NSERROR_OK
No error.
Definition: errors.h:30
Form handling public interface.
struct form_option * form_select_get_option(struct form_control *control, int item)
get a form select menus option.
Definition: form.c:1844
nserror form_select_process_selection(struct form_control *control, int item)
Process a selection from a form select menu.
Definition: form.c:1834
struct atari_hotlist hl
Definition: hotlist.c:47
nserror nsgtk_local_history_hide(void)
hide the local history window from being visible.
Interface to GTK local history manager.
Target independent plotting GTK+ interface.
nserror nsgtk_search_create(GtkBuilder *builder, struct browser_window *bw, struct gtk_search **search_out)
create text search context
Definition: search.c:284
nserror nsgtk_search_restyle(struct gtk_search *search)
update search toolbar size and style
Definition: search.c:245
nserror nsgtk_search_toggle_visibility(struct gtk_search *search)
toggle search bar visibility
Definition: search.c:225
free text page search for gtk interface
GdkPixbuf * nsgdk_pixbuf_get_from_surface(cairo_surface_t *surface, int scwidth, int scheight)
obtain a pixbuf of the specified size from a cairo surface.
Definition: gdk.c:61
GDK support functions for missing interfaces.
nserror nsgtk_warning(const char *warning, const char *detail)
Warn the user of an event.
Definition: gui.c:96
GdkPixbuf * favicon_pixbuf
favicon default pixbuf
Definition: gui.c:84
uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key)
input conversion.
Definition: gui.c:122
const struct plotter_table nsgtk_plotters
GTK plotter table.
Definition: plotters.c:647
void nsgtk_plot_caret(int x, int y, int h)
Plot a caret.
Definition: plotters.c:278
cairo_t * current_cr
Definition: plotters.c:42
nserror nsgtk_schedule(int t, void(*callback)(void *p), void *cbctx)
Definition: schedule.c:103
nserror nsgtk_throbber_get_frame(int frame, GdkPixbuf **pixbuf)
get the pixbuf of a given frame of the throbber
Definition: throbber.c:103
nserror nsgtk_toolbar_item_activate(struct nsgtk_toolbar *tb, nsgtk_toolbar_button itemid)
activate the handler for a toolbar item
Definition: toolbar.c:3740
nserror nsgtk_toolbar_restyle(struct nsgtk_toolbar *tb)
Update toolbar style and size based on current settings.
Definition: toolbar.c:3505
nserror nsgtk_toolbar_set_websearch_image(struct nsgtk_toolbar *tb, GdkPixbuf *pixbuf)
set the websearch image
Definition: toolbar.c:3713
nserror nsgtk_toolbar_set_url(struct nsgtk_toolbar *tb, nsurl *url)
Update the toolbar url entry.
Definition: toolbar.c:3662
nserror nsgtk_toolbar_position_page_info(struct nsgtk_toolbar *tb, struct nsgtk_pi_window *win)
position the page info window appropriately
Definition: toolbar.c:3857
nserror nsgtk_toolbar_position_local_history(struct nsgtk_toolbar *tb)
position the local history window appropriately
Definition: toolbar.c:3874
nserror nsgtk_toolbar_create(GtkBuilder *builder, struct browser_window *(*get_bw)(void *ctx), void *get_ctx, bool want_location_focus, struct nsgtk_toolbar **tb_out)
create a control toolbar
Definition: toolbar.c:3447
nserror nsgtk_toolbar_page_info_change(struct nsgtk_toolbar *tb)
Page info has changed state.
Definition: toolbar.c:3607
nserror nsgtk_toolbar_show(struct nsgtk_toolbar *tb, bool show)
set the toolbar to be shown or hidden
Definition: toolbar.c:3771
nserror nsgtk_toolbar_update(struct nsgtk_toolbar *tb)
Update the toolbar items being shown based on current settings.
Definition: toolbar.c:3783
nserror nsgtk_toolbar_throbber(struct nsgtk_toolbar *tb, bool active)
Start or stop a throbber in a toolbar.
Definition: toolbar.c:3550
nserror nsgtk_window_search_toggle(struct gui_window *gw)
toggle search visibility
Definition: window.c:1648
nserror nsgtk_window_position_local_history(struct gui_window *gw)
position local_history appropriately
Definition: window.c:1716
static gboolean nsgtk_paned_size_allocate_event(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
Set status bar / scroll bar proportion according to user option when pane is resized.
Definition: window.c:731
struct gui_window_table * nsgtk_window_table
Definition: window.c:1622
static void gui_window_start_selection(struct gui_window *g)
Definition: window.c:1364
static void gui_window_set_status(struct gui_window *g, const char *text)
Definition: window.c:1160
static nserror gui_window_event(struct gui_window *gw, enum gui_window_event event)
GTK window UI callback to process miscellaneous events.
Definition: window.c:1497
static void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
Definition: window.c:1226
static void gui_window_remove_caret(struct gui_window *g)
Definition: window.c:1109
static nserror gui_window_get_dimensions(struct gui_window *gw, int *width, int *height)
Find the current dimensions of a GTK browser window content area.
Definition: window.c:1350
static void gui_window_update_extent(struct gui_window *g)
Definition: window.c:1214
static gboolean nsgtk_window_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
Definition: window.c:534
static void nsgtk_paned_notify__position(GObject *gobject, GParamSpec *pspec, gpointer data)
when the pane position is changed update the user option
Definition: window.c:706
static void gui_window_set_icon(struct gui_window *gw, struct hlcache_handle *icon)
favicon setting for gtk gui window.
Definition: window.c:1048
struct gui_search_web_table * nsgtk_search_web_table
Definition: window.c:1595
static void nsgtk_select_menu_clicked(GtkCheckMenuItem *checkmenuitem, gpointer user_data)
Definition: window.c:150
void nsgtk_window_destroy_browser(struct gui_window *gw)
destroy browsing context
Definition: window.c:1663
static nserror nsgtk_window_invalidate_area(struct gui_window *g, const struct rect *rect)
Invalidates an area of a GTK browser window.
Definition: window.c:1135
static struct gui_window * gui_window_create(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags)
Create and open a gtk container (window or tab) for a browsing context.
Definition: window.c:831
struct nsgtk_scaffolding * nsgtk_get_scaffold(struct gui_window *g)
get containing nsgtk scaffolding handle from gui window handle
Definition: window.c:1626
static GtkWidget * select_menu
Definition: window.c:74
static nserror gui_window_set_url(struct gui_window *gw, nsurl *url)
GTK window UI callback when core changes the current url.
Definition: window.c:1537
nserror nsgtk_window_item_activate(struct gui_window *gw, nsgtk_toolbar_button itemid)
activate the handler for a item in a toolbar of a gui window
Definition: window.c:1656
static struct gui_window_table window_table
GTK frontend browser window operation table.
Definition: window.c:1601
static void nsgtk_window_input_method_commit(GtkIMContext *ctx, const gchar *str, gpointer data)
Definition: window.c:665
static gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
Definition: window.c:683
static gboolean nsgtk_window_draw_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
Definition: window.c:212
nserror nsgtk_window_update_all(void)
Every window will have its tab, toolbar and drawing area updated.
Definition: window.c:1671
static gboolean nsgtk_window_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
GTK signal handler for button-press-event on layout.
Definition: window.c:325
static struct form_control * select_menu_control
Definition: window.c:75
nserror nsgtk_window_position_page_info(struct gui_window *gw, struct nsgtk_pi_window *win)
position page_info appropriately
Definition: window.c:1709
static nserror throbber(struct gui_window *gw, bool active)
handle throbber changing state
Definition: window.c:1464
nserror nsgtk_window_toolbar_show(struct nsgtk_scaffolding *gs, bool show)
Windows associated with a scaffold will have their toolbar show state set.
Definition: window.c:1685
static gboolean nsgtk_window_button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
Definition: window.c:396
GtkLayout * nsgtk_window_get_layout(struct gui_window *g)
get gtk layout from gui handle
Definition: window.c:1640
static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, const struct rect *clip)
Definition: window.c:1312
static gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
Definition: window.c:252
static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
Definition: window.c:1079
static gboolean nsgtk_window_keyrelease_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
Definition: window.c:654
static nserror gui_search_web_provider_update(const char *name, struct bitmap *bitmap)
GTK UI callback when search provider details are updated.
Definition: window.c:1567
static nserror gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
Set the scroll position of a gtk browser window.
Definition: window.c:1180
static void gui_window_set_title(struct gui_window *gw, const char *title)
GTK window UI callback when core changes the current title.
Definition: window.c:1549
static struct gui_search_web_table search_web_table
GTK frontend web search operation table.
Definition: window.c:1591
struct gui_window * window_list
Definition: window.c:147
static void nsgtk_redraw_caret(struct gui_window *g)
Definition: window.c:1094
#define CONNECT(obj, sig, callback, ptr)
struct browser_window * nsgtk_get_browser_window(struct gui_window *g)
get core browsing context from gui window handle
Definition: window.c:1633
static struct browser_window * bw_from_gw(void *data)
Definition: window.c:765
#define THROBBER_FRAME_TIME
time (in ms) between throbber animation frame updates
Definition: window.c:72
static nserror page_info_change(struct gui_window *gw)
handle page info changing
Definition: window.c:1483
static void gui_window_file_gadget_open(struct gui_window *g, struct hlcache_handle *hl, struct form_control *gadget)
GTK window UI callback when core needs a file selection gadget.
Definition: window.c:1429
static bool get_tool_bar_show(void)
Definition: window.c:772
static gboolean nsgtk_window_focus_out_event(GtkWidget *widget, GdkEvent *event, gpointer data)
GTK signal handler for focus-out-event on layout.
Definition: window.c:311
static void window_destroy(GtkWidget *widget, gpointer data)
handler for gtk destroy signal on window container
Definition: window.c:747
static void gui_window_create_form_select_menu(struct gui_window *g, struct form_control *control)
Definition: window.c:1371
static void gui_window_destroy(struct gui_window *gw)
Definition: window.c:1016
nserror nsgtk_window_toolbar_update(void)
every window will have its toolbar updated to reflect user settings
Definition: window.c:1698
static gboolean nsgtk_window_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
Definition: window.c:446
static void next_throbber_frame(void *p)
Make the throbber advance to next frame.
Definition: window.c:795
Public content interface.
struct bitmap * content_get_bitmap(struct hlcache_handle *h)
Retrieve the bitmap contained in an image content.
Definition: content.c:1264
Core mouse and pointer states.
browser_mouse_state
Mouse state: 1 is primary mouse button.
Definition: mouse.h:52
@ BROWSER_MOUSE_CLICK_4
button 4 clicked.
Definition: mouse.h:76
@ BROWSER_MOUSE_PRESS_1
primary button pressed
Definition: mouse.h:59
@ BROWSER_MOUSE_CLICK_2
button 2 clicked.
Definition: mouse.h:72
@ BROWSER_MOUSE_PRESS_3
secondary button pressed
Definition: mouse.h:63
@ BROWSER_MOUSE_PRESS_4
fourth button pressed
Definition: mouse.h:65
@ BROWSER_MOUSE_PRESS_2
auxillary button pressed
Definition: mouse.h:61
@ BROWSER_MOUSE_PRESS_5
fifth button pressed
Definition: mouse.h:67
@ BROWSER_MOUSE_CLICK_3
button 3 clicked.
Definition: mouse.h:74
@ BROWSER_MOUSE_TRIPLE_CLICK
button triple clicked
Definition: mouse.h:83
@ BROWSER_MOUSE_CLICK_1
button 1 clicked.
Definition: mouse.h:70
@ BROWSER_MOUSE_MOD_2
2nd modifier key pressed (eg.
Definition: mouse.h:101
@ BROWSER_MOUSE_DOUBLE_CLICK
button double clicked
Definition: mouse.h:81
@ BROWSER_MOUSE_MOD_3
3rd modifier key pressed (eg.
Definition: mouse.h:103
@ BROWSER_MOUSE_MOD_1
1st modifier key pressed (eg.
Definition: mouse.h:99
@ BROWSER_MOUSE_DRAG_1
start of button 1 drag
Definition: mouse.h:86
@ BROWSER_MOUSE_HOLDING_2
during button 2 drag
Definition: mouse.h:96
@ BROWSER_MOUSE_HOLDING_1
during button 1 drag
Definition: mouse.h:94
@ BROWSER_MOUSE_DRAG_ON
a drag operation was started and a mouse button is still pressed
Definition: mouse.h:91
@ BROWSER_MOUSE_CLICK_5
button 5 clicked.
Definition: mouse.h:78
@ BROWSER_MOUSE_DRAG_2
start of button 2 drag
Definition: mouse.h:88
gui_pointer_shape
Definition: mouse.h:112
@ GUI_POINTER_WAIT
Definition: mouse.h:127
@ GUI_POINTER_RIGHT
Definition: mouse.h:120
@ GUI_POINTER_MOVE
Definition: mouse.h:126
@ GUI_POINTER_CARET
Definition: mouse.h:115
@ GUI_POINTER_PROGRESS
Definition: mouse.h:131
@ GUI_POINTER_RD
Definition: mouse.h:124
@ GUI_POINTER_LD
Definition: mouse.h:122
@ GUI_POINTER_NO_DROP
Definition: mouse.h:129
@ GUI_POINTER_DOWN
Definition: mouse.h:118
@ GUI_POINTER_UP
Definition: mouse.h:117
@ GUI_POINTER_RU
Definition: mouse.h:121
@ GUI_POINTER_DEFAULT
Definition: mouse.h:113
@ GUI_POINTER_HELP
Definition: mouse.h:128
@ GUI_POINTER_MENU
Definition: mouse.h:116
@ GUI_POINTER_POINT
Definition: mouse.h:114
@ GUI_POINTER_LEFT
Definition: mouse.h:119
@ GUI_POINTER_NOT_ALLOWED
Definition: mouse.h:130
@ GUI_POINTER_LU
Definition: mouse.h:123
@ GUI_POINTER_CROSS
Definition: mouse.h:125
Target independent plotting interface.
Interface to platform-specific graphical user interface window operations.
gui_window_create_flags
Window creation control flags.
Definition: window.h:66
@ GW_CREATE_TAB
Create tab in same window as existing.
Definition: window.h:69
@ GW_CREATE_FOREGROUND
Request this window/tab is foregrounded.
Definition: window.h:70
@ GW_CREATE_FOCUS_LOCATION
Definition: window.h:71
gui_window_event
Window events.
Definition: window.h:80
@ GW_EVENT_PAGE_INFO_CHANGE
Page status has changed and so the padlock should be updated.
Definition: window.h:129
@ GW_EVENT_REMOVE_CARET
Remove the caret, if present.
Definition: window.h:98
@ GW_EVENT_STOP_THROBBER
stop the navigation throbber.
Definition: window.h:108
@ GW_EVENT_UPDATE_EXTENT
Update the extent of the inside of a browser window to that of the current content.
Definition: window.h:93
@ GW_EVENT_START_SELECTION
selection started
Definition: window.h:123
@ GW_EVENT_START_THROBBER
start the navigation throbber.
Definition: window.h:103
Netsurf additional integer type formatting macros.
Interface to key press operations.
bool browser_window_key_press(struct browser_window *bw, uint32_t key)
Handle key presses in a browser window.
Definition: textinput.c:107
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
const char * messages_get(const char *key)
Fast lookup of a message by key from the standard Messages hash.
Definition: messages.c:241
Localised message support (interface).
NetSurf URL handling (interface).
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
GdkCursor * nsgtk_create_menu_cursor(void)
Creates a menu cursor from internal resources.
Definition: resources.c:148
nserror nsgtk_builder_new_from_resname(const char *resname, GtkBuilder **builder_out)
Create gtk builder object for the named ui resource.
Definition: resources.c:526
Interface to gtk builtin resource handling.
int width
Definition: gui.c:160
int height
Definition: gui.c:161
void nsgtk_scaffolding_set_title(struct gui_window *gw, const char *title)
set the title in the window
Definition: scaffolding.c:1239
struct nsgtk_scaffolding * nsgtk_new_scaffolding(struct gui_window *toplevel)
create a new scaffolding for a window.
Definition: scaffolding.c:1496
GtkNotebook * nsgtk_scaffolding_notebook(struct nsgtk_scaffolding *g)
Get the gtk notebook from a scaffold.
Definition: scaffolding.c:1316
nserror nsgtk_scaffolding_throbber(struct gui_window *gw, bool active)
Update scaffolding window when throbber state changes.
Definition: scaffolding.c:1271
GtkWindow * nsgtk_scaffolding_window(struct nsgtk_scaffolding *g)
Get the gtk window for a scaffolding.
Definition: scaffolding.c:1310
void nsgtk_scaffolding_context_menu(struct nsgtk_scaffolding *g, gdouble x, gdouble y)
Open a context sensitive menu.
Definition: scaffolding.c:1429
struct nsgtk_scaffolding * nsgtk_current_scaffolding(void)
Obtain the most recently used scaffolding element.
Definition: scaffolding.c:1473
core web search facilities interface.
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
cairo_surface_t * surface
Definition: bitmap.h:27
Browser window data.
int x
Window dimensions.
Form control.
Definition: form_internal.h:73
Option in a select.
Definition: form.h:33
bool selected
Definition: form.h:35
char * text
NUL terminated.
Definition: form.h:38
Graphical user interface browser web search function table.
Definition: searchweb.h:34
nserror(* provider_update)(const char *provider_name, struct bitmap *ico_bitmap)
called when the search provider details are updated.
Definition: searchweb.h:42
Graphical user interface window function table.
Definition: window.h:137
struct gui_window *(* create)(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags)
Create and open a gui window for a browsing context.
Definition: window.h:164
first entry in window list
Definition: gui.c:297
struct gui_window * prev
Previous in linked list.
Definition: gui.h:159
gdouble pressed_y
Definition: window.c:92
GtkIMContext * input_method
The input method to use with this window.
Definition: window.c:137
GtkLabel * status_bar
statusbar
Definition: window.c:125
GtkLayout * layout
display widget for this page or frame
Definition: window.c:116
int throb_frame
current frame of throbber
Definition: window.c:140
gdouble pressed_x
Definition: window.c:91
struct fbtk_widget_s * toolbar
Definition: gui.h:46
struct gui_window * next
list for cleanup
Definition: gui.h:159
int state
Definition: window.cpp:73
gui_pointer_shape current_pointer
caret shape for rendering
Definition: window.cpp:78
int last_y
Definition: window.cpp:79
GtkWidget * grid
The container for the layout etc.
Definition: window.c:119
struct gui_window * gui
Definition: window.c:89
gboolean waiting
Definition: window.c:93
nsbeos_scaffolding * scaffold
Definition: window.cpp:65
struct gtk_search * search
search toolbar context
Definition: window.c:110
browser_mouse_state state
Definition: window.c:94
int last_x
previous event location
Definition: window.cpp:79
int pressed_y
Definition: window.cpp:72
struct s_search_form_session * search
Definition: gui.h:158
int carety
Definition: window.cpp:77
int pressed_x
Definition: window.cpp:71
struct nsgtk_scaffolding * scaffold
The gtk scaffold object containing menu, buttons, url bar, [tabs], drawing area, etc that may contain...
Definition: window.c:82
GtkWidget * tab
handle to the the visible tab
Definition: window.c:122
struct fbtk_widget_s * hscroll
Definition: gui.h:43
struct fbtk_widget_s * vscroll
Definition: gui.h:44
struct bitmap * icon
Definition: gui.h:156
struct nsgtk_toolbar * toolbar
controls toolbar context
Definition: window.c:107
GtkPaned * paned
status pane
Definition: window.c:128
int caretx
caret dimension and location for rendering
Definition: window.cpp:77
GtkWidget * container
The top level container (tabBox)
Definition: window.c:113
struct gui_window::@32 mouse
GdkPixbuf * icon
The icon this window should have.
Definition: window.c:134
int careth
Definition: window.cpp:77
bool paned_sized
has the status pane had its first size operation yet?
Definition: window.c:131
struct browser_window * bw
The 'content' window that is rendered in the gui_window.
Definition: gui.c:315
High-level cache handle.
Definition: hlcache.c:66
GTK certificate viewing window context.
Definition: page_info.c:47
Core scaffolding structure.
Definition: scaffolding.c:64
control toolbar context
Definition: toolbar.c:170
Rectangle coordinates.
Definition: types.h:40
int x0
Definition: types.h:41
int y0
Top left.
Definition: types.h:41
int x1
Definition: types.h:42
int y1
Bottom right.
Definition: types.h:42
Redraw context.
Definition: plotters.h:51
bool interactive
Redraw to show interactive features.
Definition: plotters.h:59
nserror nsgtk_tab_set_title(GtkWidget *page, const char *title)
set the tab title
Definition: tabs.c:498
nserror nsgtk_tab_set_icon(GtkWidget *page, GdkPixbuf *pixbuf)
set the tab icon
Definition: tabs.c:470
void nsgtk_tab_options_changed(GtkNotebook *notebook)
Definition: tabs.c:372
void nsgtk_tab_add(struct gui_window *gw, GtkWidget *tab_contents, bool background, const char *title, GdkPixbuf *icon_pixbuf)
Add new gui window page to notebook.
Definition: tabs.c:452
void browser_window_remove_caret(struct browser_window *bw, bool only_hide)
Removes the caret and callback for key process.
Definition: textinput.c:88
Textual input handling interface.
nsgtk_toolbar_button
Definition: toolbar_items.h:22
@ OPENLOCATION_BUTTON
Definition: toolbar_items.h:69
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:331
#define nsoption_int(OPTION)
Get the value of an integer option.
Definition: nsoption.h:313
#define nsoption_set_int(OPTION, VALUE)
set an integer option in the default table
Definition: nsoption.h:348
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:304
uint32_t utf8_to_ucs4(const char *s_in, size_t l)
Convert a UTF-8 multibyte sequence into a single UCS4 character.
Definition: utf8.c:41
size_t utf8_next(const char *s, size_t l, size_t o)
Find next legal UTF-8 char in string.
Definition: utf8.c:129
UTF-8 manipulation functions (interface).
Interface to a number of general purpose functionality.
static nserror text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plot.c:978
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357