2022-11-14 20:41:43 +00:00
# include "config.h"
2023-02-07 13:43:00 +00:00
# include "plugins/libre_redirect/libre_redirect.h"
# include "plugins/readability/readability.h"
2023-05-14 03:24:52 +00:00
# include "plugins/shortcuts/shortcuts.h"
2023-02-07 13:43:00 +00:00
# include "plugins/style/style.h"
2024-02-11 17:25:46 +00:00
# include <stdlib.h>
# include <string.h>
# include <webkit2/webkit2.h>
2022-11-17 16:57:11 +00:00
2024-02-11 12:52:38 +00:00
/* Global declarations */
static GtkNotebook * notebook ;
static GtkWindow * window ;
2024-02-11 15:15:18 +00:00
static struct {
2024-02-11 17:25:46 +00:00
GtkHeaderBar * widget ;
GtkEntry * line ;
GtkEntryBuffer * line_text ;
enum { _SEARCH ,
_FIND ,
_HIDDEN } entry_mode ;
2024-02-11 17:01:51 +00:00
} bar ; // top bar.
2024-02-11 15:15:18 +00:00
static int num_tabs = 0 ;
2023-02-05 02:57:29 +00:00
2024-02-11 17:04:22 +00:00
/* Utils */
WebKitWebView * notebook_get_webview ( GtkNotebook * notebook )
{
return WEBKIT_WEB_VIEW ( gtk_notebook_get_nth_page (
notebook , gtk_notebook_get_current_page ( notebook ) ) ) ;
}
2024-02-11 17:23:04 +00:00
/* Load content*/
2023-03-28 16:14:13 +00:00
void load_uri ( WebKitWebView * view , const char * uri )
{
if ( g_str_has_prefix ( uri , " http:// " ) | | g_str_has_prefix ( uri , " https:// " ) | | g_str_has_prefix ( uri , " file:// " ) | | g_str_has_prefix ( uri , " about: " ) ) {
webkit_web_view_load_uri ( view , uri ) ;
} else {
2023-06-17 06:29:27 +00:00
// Check for shortcuts
int l = SHORTCUT_N + strlen ( uri ) + 1 ;
char uri_expanded [ l ] ;
str_init ( uri_expanded , l ) ;
int check = shortcut_expand ( uri , uri_expanded ) ;
if ( check = = 2 ) {
webkit_web_view_load_uri ( view , uri_expanded ) ;
} else {
// Feed into search engine.
char tmp [ strlen ( uri ) + strlen ( SEARCH ) ] ;
snprintf ( tmp , sizeof ( tmp ) , SEARCH , uri ) ;
webkit_web_view_load_uri ( view , tmp ) ;
}
2023-03-28 16:14:13 +00:00
}
}
2022-12-17 19:54:27 +00:00
2024-02-11 16:26:20 +00:00
/* Deal with new load or changed load */
2023-03-28 16:14:13 +00:00
void redirect_if_annoying ( WebKitWebView * view , const char * uri )
{
2024-02-11 17:04:22 +00:00
if ( LIBRE_REDIRECT_ENABLED ) {
int l = LIBRE_N + strlen ( uri ) + 1 ;
char uri_filtered [ l ] ;
str_init ( uri_filtered , l ) ;
2022-12-18 16:42:50 +00:00
2024-02-11 17:04:22 +00:00
int check = libre_redirect ( uri , uri_filtered ) ;
2022-12-17 19:54:27 +00:00
2024-02-11 17:04:22 +00:00
if ( check = = 2 ) {
webkit_web_view_load_uri ( view , uri_filtered ) ;
}
}
}
2024-02-11 17:25:46 +00:00
void set_custom_style ( WebKitWebView * view )
{
2024-02-11 17:04:22 +00:00
if ( CUSTOM_STYLE_ENABLED ) {
char * style_js = malloc ( STYLE_N + 1 ) ;
read_style_js ( style_js ) ;
2024-03-12 16:53:45 +00:00
webkit_web_view_evaluate_javascript ( view , style_js , - 1 , NULL , " rosenrot-style-plugin " , NULL , NULL , NULL ) ;
2024-02-11 17:04:22 +00:00
free ( style_js ) ;
2023-03-28 16:14:13 +00:00
}
2022-12-17 19:54:27 +00:00
}
2024-02-11 15:57:06 +00:00
void handle_signal_load_changed ( WebKitWebView * self , WebKitLoadEvent load_event ,
2023-03-28 16:14:13 +00:00
GtkNotebook * notebook )
2022-11-14 20:41:43 +00:00
{
2023-03-28 16:14:13 +00:00
switch ( load_event ) {
/* see <https://webkitgtk.org/reference/webkit2gtk/2.5.1/WebKitWebView.html>
*/
case WEBKIT_LOAD_STARTED :
2024-02-11 17:25:46 +00:00
set_custom_style ( self ) ;
redirect_if_annoying ( self , webkit_web_view_get_uri ( self ) ) ;
2023-03-28 16:14:13 +00:00
break ;
case WEBKIT_LOAD_REDIRECTED :
2024-02-11 17:25:46 +00:00
redirect_if_annoying ( self , webkit_web_view_get_uri ( self ) ) ;
2023-03-28 16:14:13 +00:00
break ;
case WEBKIT_LOAD_COMMITTED :
2024-02-11 17:25:46 +00:00
redirect_if_annoying ( self , webkit_web_view_get_uri ( self ) ) ;
set_custom_style ( self ) ;
2023-03-28 16:14:13 +00:00
break ;
case WEBKIT_LOAD_FINISHED : {
/* Add gtk tab title */
const char * webpage_title = webkit_web_view_get_title ( self ) ;
const int max_length = 25 ;
char tab_title [ max_length + 1 ] ;
if ( webpage_title ! = NULL ) {
for ( int i = 0 ; i < ( max_length ) ; i + + ) {
tab_title [ i ] = webpage_title [ i ] ;
if ( webpage_title [ i ] = = ' \0 ' ) {
break ;
2022-12-17 19:54:27 +00:00
}
2023-03-28 16:14:13 +00:00
}
tab_title [ max_length ] = ' \0 ' ;
2022-12-17 19:54:27 +00:00
}
2023-03-28 16:14:13 +00:00
gtk_notebook_set_tab_label_text ( notebook , GTK_WIDGET ( self ) ,
webpage_title = = NULL ? " — " : tab_title ) ;
// gtk_widget_hide(GTK_WIDGET(bar));
}
}
2022-11-14 20:41:43 +00:00
}
2024-02-11 16:26:20 +00:00
/* Create new tabs */
2024-02-11 16:15:24 +00:00
void notebook_create_new_tab ( GtkNotebook * notebook , const char * uri ) ;
2024-02-11 16:26:20 +00:00
// handle_signal_create_new_tab is bound to a signal inside notebook_create_new_tab
// and itself calls notebook_create_new_tab
// therefore we need to do a forward declaration for one of them.
2024-02-11 15:57:06 +00:00
GtkWidget * handle_signal_create_new_tab ( WebKitWebView * self ,
2023-03-28 16:14:13 +00:00
WebKitNavigationAction * navigation_action ,
GtkNotebook * notebook )
2023-06-17 06:29:27 +00:00
{
2024-02-11 15:15:18 +00:00
if ( num_tabs < MAX_NUM_TABS | | num_tabs = = 0 ) {
2023-06-17 06:29:27 +00:00
WebKitURIRequest * uri_request = webkit_navigation_action_get_request ( navigation_action ) ;
const char * uri = webkit_uri_request_get_uri ( uri_request ) ;
printf ( " Creating new window: %s \n " , uri ) ;
2024-02-11 16:15:24 +00:00
notebook_create_new_tab ( notebook , uri ) ;
2023-06-17 06:29:27 +00:00
gtk_notebook_set_show_tabs ( notebook , true ) ;
return NULL ;
} else {
2024-03-12 16:53:45 +00:00
webkit_web_view_evaluate_javascript ( self , " alert('Too many tabs, not opening a new one') " , - 1 , NULL , " rosenrot-alert-numtabs " , NULL , NULL , NULL ) ;
2023-10-06 14:44:47 +00:00
return NULL ;
2023-06-17 06:29:27 +00:00
}
2024-02-11 17:25:46 +00:00
/*
2024-02-11 16:26:20 +00:00
WebKitGTK documentation recommends returning the new webview .
I imagine that this might allow e . g . , to go back in a new tab
or generally to keep track of history .
However , this would require either modifying notebook_create_new_tab
or duplicating its contents , for unclear gain .
2023-03-28 16:14:13 +00:00
*/
2023-02-05 01:31:57 +00:00
}
2024-02-11 17:23:04 +00:00
WebKitWebView * create_new_webview ( )
{
char * style ;
WebKitSettings * settings ;
WebKitWebContext * web_context ;
WebKitCookieManager * cookiemanager ;
WebKitUserContentManager * contentmanager ;
settings = webkit_settings_new_with_settings ( WEBKIT_DEFAULT_SETTINGS , NULL ) ;
if ( CUSTOM_USER_AGENT ) {
webkit_settings_set_user_agent (
settings ,
" Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, "
" like Gecko) Chrome/110.0.0.0 Safari/537.36 " ) ;
// See: <https://www.useragents.me/> for some common user agents
}
web_context = webkit_web_context_new_with_website_data_manager (
webkit_website_data_manager_new ( CACHE , NULL ) ) ;
contentmanager = webkit_user_content_manager_new ( ) ;
cookiemanager = webkit_web_context_get_cookie_manager ( web_context ) ;
webkit_cookie_manager_set_persistent_storage (
cookiemanager , CACHE_DIR " /cookies.sqlite " ,
WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE ) ;
webkit_cookie_manager_set_accept_policy ( cookiemanager ,
WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS ) ;
if ( g_file_get_contents ( " ~/.config/rose/style.css " , & style , NULL , NULL ) )
webkit_user_content_manager_add_style_sheet (
contentmanager , webkit_user_style_sheet_new ( style , WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES , WEBKIT_USER_STYLE_LEVEL_USER , NULL , NULL ) ) ;
return g_object_new ( WEBKIT_TYPE_WEB_VIEW , " settings " , settings , " web-context " ,
web_context , " user-content-manager " , contentmanager ,
NULL ) ;
}
2024-02-11 16:15:24 +00:00
void notebook_create_new_tab ( GtkNotebook * notebook , const char * uri )
2022-11-14 20:41:43 +00:00
{
2024-02-11 17:23:04 +00:00
if ( num_tabs < MAX_NUM_TABS | | MAX_NUM_TABS = = 0 ) {
2023-06-17 06:29:27 +00:00
GdkScreen * screen = gtk_window_get_screen ( GTK_WINDOW ( window ) ) ;
GdkVisual * rgba_visual = gdk_screen_get_rgba_visual ( screen ) ;
GdkRGBA rgba ;
gdk_rgba_parse ( & rgba , BG_COLOR ) ;
2024-02-11 17:23:04 +00:00
WebKitWebView * view = create_new_webview ( ) ;
2023-06-17 06:29:27 +00:00
gtk_widget_set_visual ( GTK_WIDGET ( window ) , rgba_visual ) ;
2024-02-11 15:57:06 +00:00
g_signal_connect ( view , " load_changed " , G_CALLBACK ( handle_signal_load_changed ) , notebook ) ;
g_signal_connect ( view , " create " , G_CALLBACK ( handle_signal_create_new_tab ) , notebook ) ;
2023-06-17 06:29:27 +00:00
2024-02-11 16:26:20 +00:00
int n = gtk_notebook_append_page ( notebook , GTK_WIDGET ( view ) , NULL ) ;
2023-06-17 06:29:27 +00:00
gtk_notebook_set_tab_reorderable ( notebook , GTK_WIDGET ( view ) , true ) ;
gtk_widget_show_all ( GTK_WIDGET ( window ) ) ;
2024-02-11 15:29:36 +00:00
gtk_widget_hide ( GTK_WIDGET ( bar . widget ) ) ;
2023-06-17 06:29:27 +00:00
webkit_web_view_set_background_color ( view , & rgba ) ;
load_uri ( view , ( uri ) ? uri : HOME ) ;
2024-02-11 17:23:04 +00:00
set_custom_style ( view ) ;
2023-06-17 06:29:27 +00:00
gtk_notebook_set_current_page ( notebook , n ) ;
gtk_notebook_set_tab_label_text ( notebook , GTK_WIDGET ( view ) , " - " ) ;
webkit_web_view_set_zoom_level ( view , ZOOM ) ;
2024-02-11 15:15:18 +00:00
num_tabs + = 1 ;
2023-06-17 06:29:27 +00:00
} else {
2024-03-12 16:53:45 +00:00
webkit_web_view_evaluate_javascript ( notebook_get_webview ( notebook ) , " alert('Too many tabs, not opening a new one') " , - 1 , NULL , " rosenrot-alert-numtabs " , NULL , NULL , NULL ) ;
2023-06-17 06:29:27 +00:00
}
2022-11-14 20:41:43 +00:00
}
2024-02-11 16:14:01 +00:00
/* Top bar */
2023-03-28 16:14:13 +00:00
void show_bar ( GtkNotebook * notebook )
2022-11-14 20:41:43 +00:00
{
2024-02-11 15:15:18 +00:00
if ( bar . entry_mode = = _SEARCH ) {
2023-03-28 16:14:13 +00:00
const char * url = webkit_web_view_get_uri ( notebook_get_webview ( notebook ) ) ;
2024-02-11 15:22:14 +00:00
gtk_entry_set_placeholder_text ( bar . line , " Search " ) ;
gtk_entry_buffer_set_text ( bar . line_text , url , strlen ( url ) ) ;
2024-02-11 15:29:36 +00:00
gtk_widget_show ( GTK_WIDGET ( bar . widget ) ) ;
2024-02-11 15:22:14 +00:00
gtk_window_set_focus ( window , GTK_WIDGET ( bar . line ) ) ;
2024-02-11 15:15:18 +00:00
} else if ( bar . entry_mode = = _HIDDEN ) {
2024-02-11 15:29:36 +00:00
gtk_widget_hide ( GTK_WIDGET ( bar . widget ) ) ;
2023-03-28 16:14:13 +00:00
} else {
const char * search_text = webkit_find_controller_get_search_text (
webkit_web_view_get_find_controller ( notebook_get_webview ( notebook ) ) ) ;
if ( search_text ! = NULL )
2024-02-11 15:22:14 +00:00
gtk_entry_buffer_set_text ( bar . line_text , search_text , strlen ( search_text ) ) ;
2023-03-28 16:14:13 +00:00
2024-02-11 15:22:14 +00:00
gtk_entry_set_placeholder_text ( bar . line , " Find " ) ;
2024-02-11 15:29:36 +00:00
gtk_widget_show ( GTK_WIDGET ( bar . widget ) ) ;
2024-02-11 15:22:14 +00:00
gtk_window_set_focus ( window , GTK_WIDGET ( bar . line ) ) ;
2023-03-28 16:14:13 +00:00
}
2022-11-14 20:41:43 +00:00
}
2024-02-11 16:15:24 +00:00
// Handle what happens when the user is on the bar and presses enter
2024-02-11 16:14:01 +00:00
void handle_signal_bar_press_enter ( GtkEntry * self , GtkNotebook * notebook )
{
if ( bar . entry_mode = = _SEARCH )
load_uri ( notebook_get_webview ( notebook ) ,
gtk_entry_buffer_get_text ( bar . line_text ) ) ;
else if ( bar . entry_mode = = _FIND )
webkit_find_controller_search (
webkit_web_view_get_find_controller ( notebook_get_webview ( notebook ) ) ,
gtk_entry_buffer_get_text ( bar . line_text ) ,
WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | WEBKIT_FIND_OPTIONS_WRAP_AROUND ,
G_MAXUINT ) ;
gtk_widget_hide ( GTK_WIDGET ( bar . widget ) ) ;
}
/* Handle shortcuts */
// Act when a particular shortcut is detected
int handle_shortcut ( func id , GtkNotebook * notebook )
2022-11-14 20:41:43 +00:00
{
2023-03-28 16:14:13 +00:00
static double zoom = ZOOM ;
static bool is_fullscreen = 0 ;
2022-11-14 20:41:43 +00:00
2024-02-11 17:23:04 +00:00
WebKitWebView * view = notebook_get_webview ( notebook ) ;
2023-03-28 16:14:13 +00:00
switch ( id ) {
2023-02-05 02:11:56 +00:00
case goback :
2024-02-11 17:23:04 +00:00
webkit_web_view_go_back ( view ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
case goforward :
2024-02-11 17:23:04 +00:00
webkit_web_view_go_forward ( view ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
case refresh :
2024-02-11 17:23:04 +00:00
webkit_web_view_reload ( view ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
case refresh_force :
2024-02-11 17:23:04 +00:00
webkit_web_view_reload_bypass_cache ( view ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
case back_to_home :
2024-02-11 17:23:04 +00:00
load_uri ( view , HOME ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
case zoomin :
2024-02-11 17:23:04 +00:00
webkit_web_view_set_zoom_level ( view ,
2023-03-28 16:14:13 +00:00
( zoom + = ZOOM_VAL ) ) ;
break ;
2023-02-05 02:11:56 +00:00
case zoomout :
2024-02-11 17:23:04 +00:00
webkit_web_view_set_zoom_level ( view ,
2023-03-28 16:14:13 +00:00
( zoom - = ZOOM_VAL ) ) ;
break ;
2023-02-05 02:11:56 +00:00
case zoom_reset :
2024-02-11 17:23:04 +00:00
webkit_web_view_set_zoom_level ( view ,
2023-03-28 16:14:13 +00:00
( zoom = ZOOM ) ) ;
break ;
2023-02-05 02:11:56 +00:00
2024-01-06 15:30:09 +00:00
case prev_tab : ; // declarations aren't statements
// <https://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement>
int n = gtk_notebook_get_n_pages ( notebook ) ;
int k = gtk_notebook_get_current_page ( notebook ) ;
int l = ( n + k - 1 ) % n ;
gtk_notebook_set_current_page ( notebook , l ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
2024-01-06 15:30:09 +00:00
case next_tab : ;
int m = gtk_notebook_get_n_pages ( notebook ) ;
int i = gtk_notebook_get_current_page ( notebook ) ;
int j = ( i + 1 ) % m ;
gtk_notebook_set_current_page ( notebook , j ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
case close_tab :
2023-03-28 16:14:13 +00:00
gtk_notebook_remove_page ( notebook , gtk_notebook_get_current_page ( notebook ) ) ;
2024-02-11 15:15:18 +00:00
num_tabs - = 1 ;
2023-03-28 16:14:13 +00:00
switch ( gtk_notebook_get_n_pages ( notebook ) ) {
case 0 :
exit ( 0 ) ;
break ;
case 1 :
gtk_notebook_set_show_tabs ( notebook , false ) ;
break ;
}
2023-02-05 02:11:56 +00:00
break ;
case toggle_fullscreen :
2023-03-28 16:14:13 +00:00
if ( is_fullscreen )
gtk_window_unfullscreen ( window ) ;
else
gtk_window_fullscreen ( window ) ;
2023-02-05 02:11:56 +00:00
2023-03-28 16:14:13 +00:00
is_fullscreen = ! is_fullscreen ;
break ;
2023-02-05 02:11:56 +00:00
case show_searchbar :
2024-02-11 15:15:18 +00:00
bar . entry_mode = _SEARCH ;
2023-03-28 16:14:13 +00:00
show_bar ( notebook ) ;
break ;
2023-02-05 02:11:56 +00:00
case show_finder :
2024-02-11 15:15:18 +00:00
bar . entry_mode = _FIND ;
2023-03-28 16:14:13 +00:00
show_bar ( notebook ) ;
break ;
2023-02-05 02:11:56 +00:00
case finder_next :
2023-03-28 16:14:13 +00:00
webkit_find_controller_search_next (
2024-02-11 17:23:04 +00:00
webkit_web_view_get_find_controller ( view ) ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
case finder_prev :
2023-03-28 16:14:13 +00:00
webkit_find_controller_search_previous (
2024-02-11 17:23:04 +00:00
webkit_web_view_get_find_controller ( view ) ) ;
2023-03-28 16:14:13 +00:00
break ;
2023-02-05 02:11:56 +00:00
2023-02-07 13:17:10 +00:00
case new_tab :
2024-02-11 16:15:24 +00:00
notebook_create_new_tab ( notebook , NULL ) ;
2023-03-28 16:14:13 +00:00
gtk_notebook_set_show_tabs ( notebook , true ) ;
2024-02-11 15:15:18 +00:00
bar . entry_mode = _SEARCH ;
2023-03-28 16:14:13 +00:00
show_bar ( notebook ) ;
break ;
2023-02-05 02:11:56 +00:00
2023-02-07 13:17:10 +00:00
case hide_bar :
2024-02-11 15:15:18 +00:00
bar . entry_mode = _HIDDEN ;
2023-03-28 16:14:13 +00:00
show_bar ( notebook ) ;
break ;
case prettify : {
if ( READABILITY_ENABLED ) {
char * readability_js = malloc ( READABILITY_N + 1 ) ;
read_readability_js ( readability_js ) ;
2024-03-12 16:53:45 +00:00
webkit_web_view_evaluate_javascript ( view , readability_js , - 1 , NULL , " rosenrot-readability-plugin " , NULL , NULL , NULL ) ;
2023-03-28 16:14:13 +00:00
free ( readability_js ) ;
}
break ;
}
}
return 1 ;
2022-11-14 20:41:43 +00:00
}
2024-02-11 17:01:51 +00:00
// Listen to key presses and call shortcuts if needed.
2024-02-11 16:26:20 +00:00
int handle_signal_keypress ( void * self , GdkEvent * event , GtkNotebook * notebook )
{
( void ) self ;
for ( int i = 0 ; i < sizeof ( shortcut ) / sizeof ( shortcut [ 0 ] ) ; i + + )
if ( ( event - > key . state = = shortcut [ i ] . mod | | shortcut [ i ] . mod = = 0x0 ) & & event - > key . keyval = = shortcut [ i ] . key )
return handle_shortcut ( shortcut [ i ] . id , notebook ) ;
/*
If I wanted to bind button presses , like the extra button in the mouse ,
I would have to bind the button - press - event signal instead .
Some links in case I go down that road :
- < https : //docs.gtk.org/gtk3/signal.Widget.button-press-event.html>
- < https : //docs.gtk.org/gdk3/union.Event.html>
- https : //docs.gtk.org/gdk3/struct.EventButton.html
*/
return 0 ;
}
2022-11-14 20:41:43 +00:00
2024-02-11 12:52:38 +00:00
int main ( int argc , char * * argv )
2022-11-14 20:41:43 +00:00
{
2024-02-11 17:01:51 +00:00
/* Initialize GTK in general */
2024-02-11 17:25:46 +00:00
gtk_init ( NULL , NULL ) ; // <https://docs.gtk.org/gtk3/func.init.html>
2024-02-11 17:01:51 +00:00
g_object_set ( gtk_settings_get_default ( ) , GTK_SETTINGS_CONFIG_H , NULL ) ; // <https://docs.gtk.org/gobject/method.Object.set.html>
2024-02-11 15:57:06 +00:00
GtkCssProvider * css = gtk_css_provider_new ( ) ;
gtk_css_provider_load_from_path ( css , " /usr/share/themes/rose/style.css " , NULL ) ;
gtk_style_context_add_provider_for_screen ( gdk_screen_get_default ( ) , GTK_STYLE_PROVIDER ( css ) , 800 ) ;
2024-02-11 17:01:51 +00:00
/* Initialize GTK objects. These are declared as static globals */
2024-02-11 17:25:46 +00:00
// Notebook
2024-02-11 15:57:06 +00:00
notebook = GTK_NOTEBOOK ( gtk_notebook_new ( ) ) ;
gtk_notebook_set_show_tabs ( notebook , false ) ;
gtk_notebook_set_show_border ( notebook , false ) ;
// Window
2023-03-28 16:14:13 +00:00
window = GTK_WINDOW ( gtk_window_new ( 0 ) ) ;
gtk_window_set_default_size ( window , WIDTH , HEIGHT ) ;
2024-02-11 15:57:06 +00:00
g_signal_connect ( window , " key-press-event " , G_CALLBACK ( handle_signal_keypress ) , notebook ) ;
g_signal_connect ( window , " destroy " , G_CALLBACK ( exit ) , notebook ) ;
gtk_container_add ( GTK_CONTAINER ( window ) , GTK_WIDGET ( notebook ) ) ;
2024-02-11 15:29:36 +00:00
2024-02-11 15:57:06 +00:00
// Bar
bar . line_text = GTK_ENTRY_BUFFER ( gtk_entry_buffer_new ( " " , 0 ) ) ;
bar . line = GTK_ENTRY ( gtk_entry_new_with_buffer ( bar . line_text ) ) ;
2024-02-11 15:29:36 +00:00
gtk_entry_set_alignment ( bar . line , 0.48 ) ;
gtk_widget_set_size_request ( GTK_WIDGET ( bar . line ) , BAR_SIZE , - 1 ) ;
2024-02-11 16:14:01 +00:00
g_signal_connect ( bar . line , " activate " , G_CALLBACK ( handle_signal_bar_press_enter ) , notebook ) ;
2024-02-11 15:57:06 +00:00
bar . widget = GTK_HEADER_BAR ( gtk_header_bar_new ( ) ) ;
2024-02-11 15:29:36 +00:00
gtk_header_bar_set_custom_title ( bar . widget , GTK_WIDGET ( bar . line ) ) ;
gtk_window_set_titlebar ( window , GTK_WIDGET ( bar . widget ) ) ;
2023-03-28 16:14:13 +00:00
2024-02-11 17:01:51 +00:00
/* Load first tab */
2023-06-26 10:26:53 +00:00
char * first_uri = argc > 1 ? argv [ 1 ] : HOME ;
2024-02-11 16:15:24 +00:00
notebook_create_new_tab ( notebook , first_uri ) ;
2024-02-11 15:29:36 +00:00
2024-02-11 17:01:51 +00:00
/* Show to user */
2023-03-28 16:14:13 +00:00
gtk_widget_show_all ( GTK_WIDGET ( window ) ) ;
2024-02-11 15:29:36 +00:00
gtk_widget_hide ( GTK_WIDGET ( bar . widget ) ) ;
2023-03-28 16:14:13 +00:00
2024-02-11 17:01:51 +00:00
/* Deal with more tabs */
2023-03-28 16:14:13 +00:00
if ( argc > 2 ) {
gtk_notebook_set_show_tabs ( notebook , true ) ;
for ( int i = 2 ; i < argc ; i + + ) {
2024-02-11 16:15:24 +00:00
notebook_create_new_tab ( notebook , argv [ i ] ) ;
2023-03-28 16:14:13 +00:00
}
}
2022-11-14 20:41:43 +00:00
2023-03-28 16:14:13 +00:00
gtk_main ( ) ;
2022-11-14 20:41:43 +00:00
}