focus on your browsing
browser web-browser
at main 536 lines 15 kB view raw
1using Adw; 2using Gtk; 3using WebKit; 4using Application = Adw.Application; 5using Object = GObject.Object; 6using OuchBrowser.Utils; 7using OuchBrowser.UI; 8 9namespace OuchBrowser; 10 11public class Window 12{ 13 private string palette_state = "new_tab"; 14 15 public Window() { } 16 17 public void OnActivate(Object app, EventArgs args) 18 { 19 var application = (Application)app; 20 var window = new UI.Window(application); 21 var preferences = Preferences.New(); 22 var about = About.New(); 23 var view = new View(window.view!, window!); 24 25 SetupActions(window, application, preferences, about); 26 27 window.go_back!.SetSensitive(false); 28 window.go_forward!.SetSensitive(false); 29 window.refresh!.SetSensitive(false); 30 window.copy_link!.SetSensitive(false); 31 window.url_button!.SetSensitive(false); 32 window.website_settings!.SetSensitive(false); 33 34 // TODO: maybe make this a little bit less "hacky?" 35 window.content_sidebar_toggle!.OnClicked += (_, _) => 36 { 37 window.osv!.SetShowSidebar(true); 38 window.sidebar_toggle!.SetActive(true); 39 window.frame!.SetMarginStart(0); 40 }; 41 window.sidebar_toggle!.OnClicked += (_, _) => 42 { 43 window.frame!.SetMarginStart(10); 44 }; 45 46 window.url_entry!.OnActivate += (entry, _) => 47 { 48 string query = entry.GetBuffer().GetText(); 49 50 if (query == "") return; 51 52 if (palette_state == "new_tab") 53 { 54 Console.WriteLine($"url: {query}"); 55 Console.WriteLine($"isURL: {Url.IsUrl(query)}"); 56 Console.WriteLine($"starts with https or http: {query.StartsWith("https://") || query.StartsWith("http://")}"); 57 Console.WriteLine(""); 58 59 if (Url.IsUrl(query)) 60 { 61 if (query.StartsWith("https://") || query.StartsWith("http://")) 62 { 63 view.AddTab(query, false); 64 } 65 else 66 { 67 view.AddTab($"https://{query}", false); 68 } 69 } 70 else 71 { 72 view.AddTab($"{window.settings!.GetString("search-engine")}{query}", false); 73 } 74 } 75 else 76 { 77 TabPage page = window.view!.GetSelectedPage()!; 78 WebView webview = (WebView)page.Child!; 79 80 Console.WriteLine($"url: {query}"); 81 Console.WriteLine($"isURL: {Url.IsUrl(query)}"); 82 Console.WriteLine($"starts with https or http: {query.StartsWith("https://") || query.StartsWith("http://")}"); 83 Console.WriteLine(""); 84 85 if (Url.IsUrl(query)) 86 { 87 if (query.StartsWith("https://") || query.StartsWith("http://")) 88 { 89 webview.LoadUri(query); 90 } 91 else 92 { 93 webview.LoadUri($"https://{query}"); 94 } 95 } 96 else 97 { 98 webview.LoadUri($"{window.settings!.GetString("search-engine")}{query}"); 99 } 100 } 101 102 window.url_dialog!.ForceClose(); 103 window.url_dialog!.SetCanClose(true); 104 window.overview!.SetOpen(false); 105 }; 106 107 window.overview!.OnCreateTab += (_, _) => 108 { 109 window.ActivateAction("palette-new", null); 110 return window.view!.GetSelectedPage()!; 111 }; 112 113 window.Present(); 114 window.url_dialog!.Present(window); 115 } 116 117 public void SetupActions(UI.Window window, Application application, PreferencesDialog preferences, Adw.AboutDialog about) 118 { 119 var actions = new Actions(window, application); 120 121 actions.AddAction("palette-new", ["<Ctrl>t"], (_, _) => 122 { 123 window.overview!.SetOpen(false); 124 125 EntryBuffer buffer = EntryBuffer.New("", -1); 126 window.url_entry!.SetBuffer(buffer); 127 window.url_dialog!.Present(window); 128 window.url_entry!.GrabFocus(); 129 palette_state = "new_tab"; 130 }); 131 132 actions.AddAction("palette", ["<Ctrl>l", "<Alt>d"], (_, _) => 133 { 134 if (window.view!.GetNPages() == 0) return; 135 136 TabPage page = window.view!.GetSelectedPage()!; 137 WebView webview = (WebView)page.Child!; 138 EntryBuffer buffer = EntryBuffer.New(webview.GetUri(), -1); 139 window.url_entry!.SetBuffer(buffer); 140 window.url_dialog!.Present(window); 141 window.url_entry!.GrabFocus(); 142 palette_state = "current_tab"; 143 }); 144 145 actions.AddAction("sidebar-toggle", ["<Ctrl><Shift>s"], (_, _) => 146 { 147 if (window.view!.GetNPages() == 0) return; 148 149 if (window.osv!.GetShowSidebar()) 150 { 151 window.sidebar_toggle!.Activate(); 152 } 153 else 154 { 155 window.content_sidebar_toggle!.Activate(); 156 } 157 }); 158 159 foreach (int i in new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }) 160 { 161 actions.AddAction($"tab-{i}", [$"<Ctrl>{i}"], (_, _) => 162 { 163 if (window.view!.GetNPages() < i) return; 164 if (window.view!.GetNthPage(i - 1) == window.view!.GetSelectedPage()) return; 165 166 TabPage page = window.view!.GetNthPage(i - 1); 167 window.view!.SetSelectedPage(page); 168 169 if (!window.osv!.GetShowSidebar()) 170 { 171 Toast toast = Toast.New(page.GetTitle()); 172 toast.SetTimeout(1); 173 window.toast_overlay!.DismissAll(); 174 window.toast_overlay!.AddToast(toast); 175 } 176 }); 177 } 178 179 actions.AddAction("preferences", ["<Ctrl>comma"], (action, parameter) => 180 { 181 preferences.Present(window); 182 }); 183 184 actions.AddAction("about", [], (action, parameter) => 185 { 186 about.Present(window); 187 }); 188 189 actions.AddAction("refresh", ["<Ctrl>r"], (_, _) => 190 { 191 TabPage page = window.view!.GetSelectedPage()!; 192 WebView webview = (WebView)page.Child!; 193 194 if (window.refresh!.GetIconName() == "cross-large-symbolic") 195 { 196 webview.StopLoading(); 197 } 198 else 199 { 200 webview.Reload(); 201 } 202 }); 203 204 actions.AddAction("hard-refresh", ["<Ctrl><Shift>r"], (_, _) => 205 { 206 TabPage page = window.view!.GetSelectedPage()!; 207 WebView webview = (WebView)page.Child!; 208 209 webview.ReloadBypassCache(); 210 }); 211 212 actions.AddAction("zoom-in", ["<Ctrl>equal"], (_, _) => 213 { 214 TabPage page = window.view!.GetSelectedPage()!; 215 WebView webview = (WebView)page.Child!; 216 Toast toast = Toast.New(""); 217 218 // these levels correspond to what would be seen in chromium 219 switch (webview.GetZoomLevel()) 220 { 221 case 0.25: // 25% 222 webview.SetZoomLevel(0.33); // 33% 223 toast.SetTitle("33%"); 224 toast.SetTimeout(1); 225 window.toast_overlay!.DismissAll(); 226 window.toast_overlay!.AddToast(toast); 227 break; 228 case 0.33: // 33% 229 webview.SetZoomLevel(0.5); // 50% 230 toast.SetTitle("50%"); 231 toast.SetTimeout(1); 232 window.toast_overlay!.DismissAll(); 233 window.toast_overlay!.AddToast(toast); 234 break; 235 case 0.5: // 50% 236 webview.SetZoomLevel(0.67); // 67% 237 toast.SetTitle("67%"); 238 toast.SetTimeout(1); 239 window.toast_overlay!.DismissAll(); 240 window.toast_overlay!.AddToast(toast); 241 break; 242 case 0.67: // 67% 243 webview.SetZoomLevel(0.75); // 75% 244 toast.SetTitle("75%"); 245 toast.SetTimeout(1); 246 window.toast_overlay!.DismissAll(); 247 window.toast_overlay!.AddToast(toast); 248 break; 249 case 0.75: // 75% 250 webview.SetZoomLevel(0.8); // 80% 251 toast.SetTitle("80%"); 252 toast.SetTimeout(1); 253 window.toast_overlay!.DismissAll(); 254 window.toast_overlay!.AddToast(toast); 255 break; 256 case 0.8: // 80% 257 webview.SetZoomLevel(0.9); // 90% 258 toast.SetTitle("90%"); 259 toast.SetTimeout(1); 260 window.toast_overlay!.DismissAll(); 261 window.toast_overlay!.AddToast(toast); 262 break; 263 case 0.9: // 90% 264 webview.SetZoomLevel(1); // 100% 265 toast.SetTitle("100%"); 266 toast.SetTimeout(1); 267 window.toast_overlay!.DismissAll(); 268 window.toast_overlay!.AddToast(toast); 269 break; 270 case 1: // 100% 271 webview.SetZoomLevel(1.1); // 110% 272 toast.SetTitle("110%"); 273 toast.SetTimeout(1); 274 window.toast_overlay!.DismissAll(); 275 window.toast_overlay!.AddToast(toast); 276 break; 277 case 1.1: // 110% 278 webview.SetZoomLevel(1.25); // 125% 279 toast.SetTitle("125%"); 280 toast.SetTimeout(1); 281 window.toast_overlay!.DismissAll(); 282 window.toast_overlay!.AddToast(toast); 283 break; 284 case 1.25: // 125% 285 webview.SetZoomLevel(1.5); // 150% 286 toast.SetTitle("150%"); 287 toast.SetTimeout(1); 288 window.toast_overlay!.DismissAll(); 289 window.toast_overlay!.AddToast(toast); 290 break; 291 case 1.5: // 150% 292 webview.SetZoomLevel(1.75); // 175% 293 toast.SetTitle("175%"); 294 toast.SetTimeout(1); 295 window.toast_overlay!.DismissAll(); 296 window.toast_overlay!.AddToast(toast); 297 break; 298 case 1.75: // 175% 299 webview.SetZoomLevel(2); // 200% 300 toast.SetTitle("200%"); 301 toast.SetTimeout(1); 302 window.toast_overlay!.DismissAll(); 303 window.toast_overlay!.AddToast(toast); 304 break; 305 case 2: // 200% 306 webview.SetZoomLevel(2.5); // 250% 307 toast.SetTitle("250%"); 308 toast.SetTimeout(1); 309 window.toast_overlay!.DismissAll(); 310 window.toast_overlay!.AddToast(toast); 311 break; 312 case 2.5: // 250% 313 webview.SetZoomLevel(3); // 300% 314 toast.SetTitle("300%"); 315 toast.SetTimeout(1); 316 window.toast_overlay!.DismissAll(); 317 window.toast_overlay!.AddToast(toast); 318 break; 319 case 3: // 300% 320 webview.SetZoomLevel(4); // 400% 321 toast.SetTitle("400%"); 322 toast.SetTimeout(1); 323 window.toast_overlay!.DismissAll(); 324 window.toast_overlay!.AddToast(toast); 325 break; 326 case 4: // 400% 327 webview.SetZoomLevel(5); // 400% 328 toast.SetTitle("500%"); 329 toast.SetTimeout(1); 330 window.toast_overlay!.DismissAll(); 331 window.toast_overlay!.AddToast(toast); 332 break; 333 case 5: // 500% 334 Gdk.Display.GetDefault()!.Beep(); 335 break; 336 } 337 }); 338 339 actions.AddAction("zoom-out", ["<Ctrl>minus"], (_, _) => 340 { 341 TabPage page = window.view!.GetSelectedPage()!; 342 WebView webview = (WebView)page.Child!; 343 Toast toast = Toast.New(""); 344 345 // these levels correspond to what would be seen in chromium 346 switch (webview.GetZoomLevel()) 347 { 348 case 5: // 500% 349 webview.SetZoomLevel(4); // 400% 350 toast.SetTitle("400%"); 351 toast.SetTimeout(1); 352 window.toast_overlay!.DismissAll(); 353 window.toast_overlay!.AddToast(toast); 354 break; 355 case 4: // 400% 356 webview.SetZoomLevel(3); // 300% 357 toast.SetTitle("300%"); 358 toast.SetTimeout(1); 359 window.toast_overlay!.DismissAll(); 360 window.toast_overlay!.AddToast(toast); 361 break; 362 case 3: // 300% 363 webview.SetZoomLevel(2.5); // 150% 364 toast.SetTitle("250%"); 365 toast.SetTimeout(1); 366 window.toast_overlay!.DismissAll(); 367 window.toast_overlay!.AddToast(toast); 368 break; 369 case 2.5: // 250% 370 webview.SetZoomLevel(2); // 200% 371 toast.SetTitle("200%"); 372 toast.SetTimeout(1); 373 window.toast_overlay!.DismissAll(); 374 window.toast_overlay!.AddToast(toast); 375 break; 376 case 2: // 200% 377 webview.SetZoomLevel(1.75); // 175% 378 toast.SetTitle("175%"); 379 toast.SetTimeout(1); 380 window.toast_overlay!.DismissAll(); 381 window.toast_overlay!.AddToast(toast); 382 break; 383 case 1.75: // 175% 384 webview.SetZoomLevel(1.5); // 150% 385 toast.SetTitle("150%"); 386 toast.SetTimeout(1); 387 window.toast_overlay!.DismissAll(); 388 window.toast_overlay!.AddToast(toast); 389 break; 390 case 1.5: // 150% 391 webview.SetZoomLevel(1.25); // 125% 392 toast.SetTitle("125%"); 393 toast.SetTimeout(1); 394 window.toast_overlay!.DismissAll(); 395 window.toast_overlay!.AddToast(toast); 396 break; 397 case 1.25: // 125% 398 webview.SetZoomLevel(1.1); // 400% 399 toast.SetTitle("110%"); 400 toast.SetTimeout(1); 401 window.toast_overlay!.DismissAll(); 402 window.toast_overlay!.AddToast(toast); 403 break; 404 case 1.1: // 110% 405 webview.SetZoomLevel(1); // 400% 406 toast.SetTitle("100%"); 407 toast.SetTimeout(1); 408 window.toast_overlay!.DismissAll(); 409 window.toast_overlay!.AddToast(toast); 410 break; 411 case 1: // 100% 412 webview.SetZoomLevel(0.9); // 400% 413 toast.SetTitle("90%"); 414 toast.SetTimeout(1); 415 window.toast_overlay!.DismissAll(); 416 window.toast_overlay!.AddToast(toast); 417 break; 418 case 0.9: // 90% 419 webview.SetZoomLevel(0.8); // 80% 420 toast.SetTitle("80%"); 421 toast.SetTimeout(1); 422 window.toast_overlay!.DismissAll(); 423 window.toast_overlay!.AddToast(toast); 424 break; 425 case 0.8: // 80% 426 webview.SetZoomLevel(0.75); // 75% 427 toast.SetTitle("75%"); 428 toast.SetTimeout(1); 429 window.toast_overlay!.DismissAll(); 430 window.toast_overlay!.AddToast(toast); 431 break; 432 case 0.75: // 75% 433 webview.SetZoomLevel(0.67); // 67% 434 toast.SetTitle("67%"); 435 toast.SetTimeout(1); 436 window.toast_overlay!.DismissAll(); 437 window.toast_overlay!.AddToast(toast); 438 break; 439 case 0.67: // 67% 440 webview.SetZoomLevel(0.5); // 67% 441 toast.SetTitle("50%"); 442 toast.SetTimeout(1); 443 window.toast_overlay!.DismissAll(); 444 window.toast_overlay!.AddToast(toast); 445 break; 446 case 0.5: // 50% 447 webview.SetZoomLevel(0.33); // 33% 448 toast.SetTitle("33%"); 449 toast.SetTimeout(1); 450 window.toast_overlay!.DismissAll(); 451 window.toast_overlay!.AddToast(toast); 452 break; 453 case 0.33: // 33% 454 webview.SetZoomLevel(0.25); // 25% 455 toast.SetTitle("25%"); 456 toast.SetTimeout(1); 457 window.toast_overlay!.DismissAll(); 458 window.toast_overlay!.AddToast(toast); 459 break; 460 case 0.25: // 25% 461 Gdk.Display.GetDefault()!.Beep(); 462 break; 463 } 464 }); 465 466 actions.AddAction("tab-close", ["<Ctrl>w"], (_, _) => 467 { 468 if (window.view!.GetNPages() == 0) 469 { 470 window.Close(); 471 } 472 else 473 { 474 TabPage page = window.view!.GetSelectedPage()!; 475 WebView webview = (WebView)page.Child!; 476 477 webview.TryClose(); 478 window.view!.ClosePage(window.view!.GetSelectedPage()!); 479 if (window.view!.GetNPages() == 0) 480 { 481 window.refresh!.SetSensitive(false); 482 window.go_back!.SetSensitive(false); 483 window.go_forward!.SetSensitive(false); 484 window.url_button!.SetSensitive(false); 485 window.copy_link!.SetSensitive(false); 486 window.website_settings!.SetSensitive(false); 487 window.sidebar_toggle!.SetSensitive(false); 488 window.sidebar_toggle!.SetActive(true); 489 window.hostname!.SetLabel(""); 490 window.osv!.SetShowSidebar(true); 491 } 492 } 493 }); 494 495 actions.AddAction("go-back", ["<Ctrl>Left"], (_, _) => 496 { 497 if (window.view!.GetNPages() == 0) return; 498 499 TabPage page = window.view!.GetSelectedPage()!; 500 WebView webview = (WebView)page.Child!; 501 502 webview.GoBack(); 503 }); 504 505 actions.AddAction("go-forward", ["<Ctrl>Right"], (_, _) => 506 { 507 if (window.view!.GetNPages() == 0) return; 508 509 TabPage page = window.view!.GetSelectedPage()!; 510 WebView webview = (WebView)page.Child!; 511 512 webview.GoForward(); 513 }); 514 515 actions.AddAction("copy-link", ["<Ctrl><Shift>c"], (_, _) => 516 { 517 if (window.view!.GetNPages() == 0) return; 518 519 TabPage page = window.view!.GetSelectedPage()!; 520 WebView webview = (WebView)page.Child!; 521 Toast toast = Toast.New(""); 522 523 string uri = webview.GetUri(); 524 Gdk.Display display = Gdk.Display.GetDefault()!; 525 Gdk.Clipboard clipboard = display!.GetClipboard(); 526 clipboard.SetText(uri); 527 528 toast.SetTitle(window.gettext.GetString("Link copied")); 529 toast.SetTimeout(1); 530 window.toast_overlay!.DismissAll(); 531 window.toast_overlay!.AddToast(toast); 532 533 webview.GoForward(); 534 }); 535 } 536}