{"componentChunkName":"component---src-templates-post-jsx","path":"/blog/polypane-22-1-true-browser-tabs-and-a-new-split-layout/","result":{"data":{"mdx":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nconst _frontmatter = {\n  \"title\": \"Polypane 22.1: true browser tabs and a new split layout\",\n  \"cover\": \"/img/mail/icon.svg\",\n  \"date\": \"2024-12-19\",\n  \"type\": [\"announcement\"]\n};\nconst layoutProps = {\n  _frontmatter\n};\nconst MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  let {\n    components\n  } = _ref,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, `In this last full release of 2024 we're shipping two big new features and a host of improvements and fixes. The biggest new feature is the introduction of true browser tabs that keep their state, and the second is the new split layout.`), mdx(PolypaneIntro, {\n    mdxType: \"PolypaneIntro\"\n  }), mdx(\"h2\", {\n    \"id\": \"true-browser-tabs\"\n  }, `True browser tabs`), mdx(\"p\", null, `Browser tabs landed all the way back in `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/blog/polypane-3-browser-tabs-and-dark-mode-emulation/\"\n  }), `Polypane 3`), `, where I implemented tabs with one caveat: unfocused tabs were not kept in memory, and reloaded when you focused them.`), mdx(\"p\", null, `This helped keep the memory requirements down but came at the cost of not being able to quickly tab over to a docs tab and then tab back. While Polypane has the `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/browse/\"\n  }), `browse panel`), ` for those pages, this back-and-forth tabbing is engrained in many developers' workflow.`), mdx(\"video\", {\n    src: tabs,\n    muted: true,\n    controls: true,\n    preload: \"auto\",\n    loading: \"lazy\",\n    playsInline: true,\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `In Polypane 22.1 I've completely rewritten the tab logic to keep tabs in memory and keep their state. This means that when you switch tabs, the tab is not reloaded but instead kept in memory, with the full state of your pages and the panel retained. This makes tabbing between tabs much faster and more reliable, at the cost of using more memory in total.`), mdx(\"p\", null, `To manage memory, Polypane will let you mark tabs as being allowed to go to sleep when not active from their context menu. This will unload the tab from memory and reload it when you switch back to it.`), mdx(\"h3\", {\n    \"id\": \"search-now-also-happens-in-regular-tabs\"\n  }, `Search now also happens in regular tabs`), mdx(\"p\", null, `When performing a search, Polypane previously opened that in the Browse panel. Now search happens in the current tab just like regular browsers. As a result we've also moved the search management UI to the main browser instead of the browse panel.`), mdx(\"h2\", {\n    \"id\": \"split-layouts\"\n  }, `Split layouts`), mdx(\"p\", null, mdx(\"em\", {\n    parentName: \"p\"\n  }, `So hot right now.`)), mdx(\"video\", {\n    src: sohotrightnow,\n    muted: true,\n    controls: true,\n    preload: \"auto\",\n    loading: \"lazy\",\n    playsInline: true,\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `Joking aside, the split layout is a new layout option that gives you two panes side by side with a resizable divider in the middle.`), mdx(\"video\", {\n    src: splitview,\n    muted: true,\n    controls: true,\n    preload: \"auto\",\n    loading: \"lazy\",\n    playsInline: true,\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `This is useful if you want `, mdx(\"em\", {\n    parentName: \"p\"\n  }, `some`), ` Polypane (like a single desktop view and a mobile view to keep an eye on), or if you want to compare different pages side by side (by turning off `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/emulation/#sync-navigation\"\n  }), `navigation sync`), `).`), mdx(\"p\", null, `Beyond the two panes being automatically sized horizontally, everything else still works as you'd expect: you can still resize them vertically and all the emulation options, debug tools and panels still work.`), mdx(\"h2\", {\n    \"id\": \"astigmatism-simulators\"\n  }, `Astigmatism simulators`), mdx(\"p\", null, `Polypane has had astigmatism simulators and while they did a really good job of showing how texts on screens can get 'doubled' for people with astigmatism, they lacked the simulation of the way light gets bend into streaks.`), mdx(\"video\", {\n    src: astigmatism,\n    muted: true,\n    controls: true,\n    preload: \"auto\",\n    loading: \"lazy\",\n    playsInline: true,\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `To be honest, I didn't think it was possible to simulate light streaking at an angle, but `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://cubiq.dev\"\n  }), `Kuba`), ` proved me wrong and created these amazing looking simulators that are fully interactive.`), mdx(\"h2\", {\n    \"id\": \"ui-updates\"\n  }, `UI updates`), mdx(\"p\", null, `Over the next couple of releases we're doing a small UI refresh to clean up the UI where possible, improve colors and increase consistency across the app. This release has a few of those changes, with more to come in the future.`), mdx(\"p\", null, `Notable in this release is that fonts should be more readable, icons in the address bar are more consistent and the pane headers has been realigned to the grid.`), mdx(\"h3\", {\n    \"id\": \"address-bar\"\n  }, `Address bar`), mdx(\"p\", null, `Additionally I've taken another look at how the address bar sorts suggestions and made the URL length part of the sorting logic. If you switch between a lot of local server ports like me, this should make your life a little easier.`), mdx(\"p\", null, `The address bar now also prefers matches to the URL rather than the title, which results in slightly more predictable sort ordering.`), mdx(\"h3\", {\n    \"id\": \"web-security-warning\"\n  }, `Web security warning`), mdx(\"p\", null, `When web security is disabled in the browser, Polypane will now show a warning in the address bar. This is to prevent you from accidentally working on a site with security disabled.`), mdx(\"img\", {\n    src: websecurity,\n    className: \"imgshadow\",\n    alt: \"Polypane showing a warning in the address bar when web security is disabled\"\n  }), mdx(\"h3\", {\n    \"id\": \"coming-ui-updates\"\n  }, `Coming UI updates`), mdx(\"p\", null, `Future releases will look into the color scheme of at least light mode as well as the layout of the panels. The goal here is to make incremental improvements without changing the overall look and feel of the app.`), mdx(\"h2\", {\n    \"id\": \"support-for-blob-and-data-urls\"\n  }, `Support for blob: and data: URLs`), mdx(\"p\", null, `Polypane now supports `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `blob:`), ` and `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `data:`), ` URLs. This means that if you're working with these URLs in your development environment, you can now open them in Polypane and they will work as expected.`), mdx(\"p\", null, `While I have used `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `blob:`), ` urls to create downloads in the past, you can also assign blobs to actual URLs and open those. This is how `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://backers.webawesome.com/docs/components/page\"\n  }), `Web Awesome`), ` creates their full-page examples, and those didn't open in Polypane because it rejected the `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `blob:https://`), ` protocol.`), mdx(\"img\", {\n    src: bloburls,\n    className: \"imgshadow\",\n    alt: \"Polypane showing a blob url\"\n  }), mdx(\"p\", null, `After `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://bsky.app/profile/jpzwarte.bsky.social/post/3ld3xr7cris2r\"\n  }), `Jeroen`), ` asked about it on Bluesky (we're on bluesky: `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://bsky.app/profile/polypane.app\"\n  }), `@polypane.app`), `!) I couldn't help but be nerd-sniped into adding support for them.`), mdx(\"img\", {\n    src: dataurls,\n    className: \"imgshadow\",\n    alt: \"Polypane showing a data url\"\n  }), mdx(\"p\", null, `While implementing that, I also made sure `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `data:`), ` support was added (which, coincidentally, `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://mastodon.social/@FirefoxDevTools/113639897478846319\"\n  }), `@firefoxdevtools`), ` asked about on Mastodon!)`), mdx(\"h2\", {\n    \"id\": \"performance-improvements\"\n  }, `Performance improvements`), mdx(\"p\", null, `We've identified several more bottlenecks for large DOM pages and improved performance in those situations.`), mdx(\"p\", null, `Additionally, we've made sure that scroll actions will prevent other more expensive actions from running, which should make scrolling in Polypane feel smoother.`), mdx(\"p\", null, `In this release we've also updated to React 19 which comes with its own set of performance improvements meaning the UI should also feel snappier.`), mdx(\"h2\", {\n    \"id\": \"elements-panel-improvements\"\n  }, `Elements panel improvements`), mdx(\"p\", null, `The elements panel has seen a bunch of improvements:`), mdx(\"h3\", {\n    \"id\": \"warning-for-allunset\"\n  }, `Warning for `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `all:unset`)), mdx(\"p\", null, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `all:unset`), ` is rarely what you want to do in CSS and can have unintended consequences (like also removing all focus styling). When you use all:unset in your CSS we'll show a info icon next to the declaration.`), mdx(\"img\", {\n    src: unset,\n    className: \"imgshadow\",\n    alt: \"all:unset in the elements panel\"\n  }), mdx(\"h3\", {\n    \"id\": \"mouse-wheel-to-increasedecrease-numbers\"\n  }, `Mouse wheel to increase/decrease numbers`), mdx(\"p\", null, `After focusing a number in the elements panel you can now also increase and decrease it with the mouse wheel, along with the up and down arrow keys that already worked in previous releases.`), mdx(\"p\", null, `Like the arrow keys, this will increase or decrease the number by 1, by 10 when you hold `, mdx(ShortCutDisplay, {\n    shiftKey: true,\n    mdxType: \"ShortCutDisplay\"\n  }), `, by 100 when you hold `, mdx(ShortCutDisplay, {\n    cmdKey: true,\n    mdxType: \"ShortCutDisplay\"\n  }), ` and by 0.1 when you hold `, mdx(ShortCutDisplay, {\n    altKey: true,\n    mdxType: \"ShortCutDisplay\"\n  }), `.`), mdx(\"h3\", {\n    \"id\": \"stylesheets-are-now-clickable\"\n  }, `Stylesheets are now clickable`), mdx(\"p\", null, `You can now click on a stylesheet in the elements panel to inspect it. If it's an external stylesheet it will be opened in the `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/browse/\"\n  }), `Browse panel`), `. If it's from a style element that element will be focused in the Elements panel itself.`), mdx(\"h3\", {\n    \"id\": \"better-css-selector-generation\"\n  }, `Better CSS selector generation`), mdx(\"p\", null, `The CSS selector generator is now faster and avoids unstable css-in-js selectors. This means that when you're using css-in-js libraries like styled-components, the generated selectors will be more stable and less likely to change.`), mdx(\"p\", null, `This makes the generated CSS selectors more reliable to use for automated testing.`), mdx(\"h3\", {\n    \"id\": \"color-previews-for-inherit-and-currentcolor\"\n  }, `Color previews for `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `inherit`), ` and `, mdx(\"code\", _extends({\n    parentName: \"h3\"\n  }, {\n    \"className\": \"language-text\"\n  }), `currentcolor`)), mdx(\"img\", {\n    src: colorpreviews,\n    className: \"imgshadow\",\n    alt: \"different css properties using inherit and currentcolor all showing a color swatch preview\"\n  }), mdx(\"p\", null, `When using `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `inherit`), ` or `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `currentcolor`), ` as a value for a color property (or part of one), the color preview will now show the actual color that is used.`), mdx(\"h2\", {\n    \"id\": \"outline-panel-improvements\"\n  }, `Outline panel improvements`), mdx(\"p\", null, `I want to give a quick shout-out here to `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://yatil.net\"\n  }), `Eric`), ` and `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://www.matuzo.at/\"\n  }), `Manuel`), `, both of who have been providing a lot of very valuable feedback regarding existing features as well as insights into the correct interpretation of various accessibility-related standards.`), mdx(\"h3\", {\n    \"id\": \"presentational-and-content-images\"\n  }, `Presentational and content images`), mdx(\"p\", null, `The image outline now clearly shows the difference between content and presentational images, and if you're only concerned about the content images you can hide the presentational ones.`), mdx(\"img\", {\n    src: presentationalimages,\n    className: \"imgshadow\",\n    alt: \"Outline panel showing a list of images, some marked as content and some as presentational\"\n  }), mdx(\"p\", null, `Presentational images are images that don't convey any information. They are marked with a role of `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `none`), `/`, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `presentation`), ` or with `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `aria-hidden`), `, which is a slightly different signal than a present but empty `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `alt`), ` attribute.`), mdx(\"h3\", {\n    \"id\": \"warnings-for-repeated-accessible-names\"\n  }, `Warnings for repeated accessible names`), mdx(\"p\", null, `In the heading overview we warn about repeated header text. We now do the same in the accessibility panel for accessible names. Using the same text for multiple elements can be confusing for screen reader users.`), mdx(\"p\", null, `While implementing this we found a bug in the way our custom accessible name algorithm worked when elements had self-referential `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `aria-labelledby`), ` attributes. This has been fixed.`), mdx(\"h3\", {\n    \"id\": \"focus-order\"\n  }, `Focus order`), mdx(\"p\", null, `There are `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"https://yatil.net/blog/focusable-ui-elements\"\n  }), `two types of focus`), `:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Elements marked as focusable in the accessibility tree are programatically focusable (you can do `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `elem.focus()`), ` on them)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, `Elements in the focus order (you can tab to them)`)), mdx(\"p\", null, `Since implementing the accessibility tree in Polypane, we've incorrectly conflated the two in the focus order outline.`), mdx(\"p\", null, `This has now been fixed, and instead we show a warning for elements that you'd expect to be in the focus order but are not.`), mdx(\"h4\", {\n    \"id\": \"late-discovered-tab-order\"\n  }, `Late discovered tab order`), mdx(\"p\", null, `Late discovered focusable elements are now added in the correct order in both the Accessibility tree and the focus order.`), mdx(\"video\", {\n    src: latefocus,\n    muted: true,\n    controls: true,\n    preload: \"auto\",\n    loading: \"lazy\",\n    playsInline: true,\n    className: \"imgshadow\",\n    style: {\n      maxWidth: '100%'\n    }\n  }), mdx(\"p\", null, `What are late discovered focusable elements? Elements that can be tabbed to but that are inside an element that is hidden from assistive technologies are not in the accessibility tree until you tab to them. Chromium automatically removed for example an `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `aria-hidden`), ` attribute if this happens.`), mdx(\"h2\", {\n    \"id\": \"meta-panel-improvements\"\n  }, `Meta panel improvements`), mdx(\"p\", null, `Bluesky, Mastodon and Google all had updates to their social card designs so in Polypane they're now up to date.`), mdx(\"img\", {\n    src: blueskypp221,\n    className: \"imgshadow\",\n    alt: \"Bluesky preview of polypane.app\"\n  }), mdx(\"p\", null, `Bluesky has a new order and shows a little globe icon for the URL, Mastodon now shows relative time for articles and has a few new ways to get the Author, and Google partially reverted to a previous design.`), mdx(\"h2\", {\n    \"id\": \"web-vitals-updates\"\n  }, `Web vitals updates`), mdx(\"p\", null, `We've removed FID from the list of web vitals, as the web vitals library no longer reports it.`), mdx(\"p\", null, `We've also updated the way data gets displayed in the popop so you can see the difference between the web vitals reporter not having gathered enough info yet, or it having gathered info but the value being zero.`), mdx(\"h2\", {\n    \"id\": \"improvements-to-the-windows-platform\"\n  }, `Improvements to the Windows platform`), mdx(\"p\", null, `I recently upgraded the windows device I use for testing Polypane (I went from a 1st gen Surface Go with Windows 10 to a Lenovo Ideapad 5 with Windows 11) and that has allowed me to make some Windows-specific improvements:`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Native titlebar controls`), `: Polypane now uses native titlebar controls everywhere, So you can hold maximize to show the alignment menu.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Sharp looking installer`), ` The text in the installer was very blurry on High DPI screens, a common issue with the NSIS installers we use. There's a non-default option to match the DPI of the screen so I've enabled that.`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Touch pane resizing`), `: If you have a touch screen, you can now also tap and drag the panes and side panel to resize them.`)), mdx(\"h2\", {\n    \"id\": \"middle-mouse-click-to-drag\"\n  }, `Middle mouse click to drag`), mdx(\"p\", null, `There's a bunch of different ways to `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/docs/layouts/#horizontal-scrolling\"\n  }), `drag the horizontal and vertical layouts`), `. One of the ways is holding `, mdx(\"code\", _extends({\n    parentName: \"p\"\n  }, {\n    \"className\": \"language-text\"\n  }), `spacebar`), ` and click + move, which is how a lot of design tools allow panning.`), mdx(\"p\", null, `What I didn't know was that those same design tools also support doing this with just a mouse wheel hold! So that now also works.`), mdx(\"h2\", {\n    \"id\": \"notable-fixes\"\n  }, `Notable fixes`), mdx(\"p\", null, `There are a couple of notable fixes in this release:`), mdx(\"h3\", {\n    \"id\": \"dark-mode-devtools\"\n  }, `Dark mode devtools`), mdx(\"p\", null, `The Chromium devtools now properly start in dark mode when you're in dark mode in Polypane. This was an electron bug that took a while for the fix to land but I'm glad it's here.`), mdx(\"p\", null, `Apologies for all the flashes of bright light, folks!`), mdx(\"h3\", {\n    \"id\": \"clean-up-of-chromium-flags\"\n  }, `Clean up of Chromium flags`), mdx(\"p\", null, `We've cleaned up some of the Chromium flags we were using, as some causes rendering issues to appear on specific pages (one had its header completely missing!).`), mdx(\"h3\", {\n    \"id\": \"connection-errors\"\n  }, `Connection errors`), mdx(\"p\", null, `When you have a connection error, Polypane will clear the web vitals and console stats. This prevents stale data from showing up in the UI.`), mdx(\"h2\", {\n    \"id\": \"get-polypane-221\"\n  }, `Get Polypane 22.1`), mdx(\"p\", null, `Polypane is available for Windows, Mac and Linux (.deb or AppImage) in both 64 bit and ARM versions.`), mdx(\"p\", null, `Polypane automatically updates on Mac, Windows and on Linux when using the AppImage. Otherwise, go to `, mdx(\"a\", _extends({\n    parentName: \"p\"\n  }, {\n    \"href\": \"/download/\"\n  }), `the download page`), ` to download the latest version!`), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Don't have Polypane yet? There is a 14 day trial available. `, mdx(\"a\", _extends({\n    parentName: \"strong\"\n  }, {\n    \"href\": \"https://dashboard.polypane.app/register\"\n  }), `Try it for free`), `.`), ` No credit card needed.`)), mdx(\"h2\", {\n    \"id\": \"happy-new-year\"\n  }, `Happy new year!`), mdx(\"p\", null, `This is the 17th and last full release of 2024, and I want to thank you all for your support, feedback and bug reports.`), mdx(\"p\", null, `I hope you have a great holiday season. I'll see you all in 2025!`), mdx(\"h2\", {\n    \"id\": \"polypane-2211-changelog\"\n  }, `Polypane 22.1.1 Changelog`), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Show find in page UI again (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Focus order works for SPAs again`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Focus order correctly differentiates between programmatically focusable divs and keyboard focusable scrollers`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Panes animate in and out again, fixes onboarding (Thank Oliy!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Social media previews using GIF now show the first frame again`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Some extensions no longer installed correctly due to Chrome store changes`)), mdx(\"h2\", {\n    \"id\": \"polypane-221-changelog\"\n  }, `Polypane 22.1 Changelog`), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `New`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` True browser tabs that keep their state`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Split layout`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Astigmatism simulators (Thanks Kuba!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `New`), ` Support for blob: and data: URLs (Thanks Jeroen!)`)), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Improvements`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Better performance during synced scrolling`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Styling changes for better readability`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Better Address bar sorting logic`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Show warning in address bar when web security is disabled (Thanks Lloyd!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Performance for large DOMs (Thanks Luke!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Middle-click to drag now works in horizontal and vertical layous (Thanks Sil!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Warning icons when `, mdx(\"code\", _extends({\n    parentName: \"li\"\n  }, {\n    \"className\": \"language-text\"\n  }), `all:unset`), ` is used (Thanks Marcus!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Suggestions no longer get applied on hover`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Stylesheets are now clickable to inspect them (Thanks Marc!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Better support for SVGs encoded in CSS values (Thanks Philip!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Increase/decrease numbers with mouse wheel`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: CSS selector generation is now faster and avoids unstable css-in-js selectors`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Elements panel: Support color previews and editing for inherit and currentcolor`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Updated Mastodon design`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Updated Bluesky design`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Updated Google design`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Meta panel: Shorter warning for tab target sizes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Web vitals: Removed FID from the list of web vitals`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Web vitals: Show difference between no data yet, and the value being 0`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Web vitals: Updated INP data to be more accurate`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: Focus order overlay now takes tabindex into account (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: List items that could be in the focus order but are not now`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: Improved logic for generic roles with computed name in a11y tree (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: show warnings for repeating computedNames`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: Clearly show difference between content and presentational images (Thanks Eric!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Outline panel: checkbox option to hide presentational images`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Live CSS panel: Introduced the `, mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"https://kilianvalkhof.com/2024/css-html/an-outline-version-of-the-new-css-logo/\"\n  }), `new CSS logo`)), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Live CSS Panel: Faster SCSS parsing`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Live CSS Panel: Better update logic`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Debug tools: Updated A11y.css`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Debug tools: Placeholderifier with only translatable now supports translatable=no on parent elements (Thanks Robbert!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Windows: Use native titlebar controls`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Windows: Fix blurry text in installer`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Windows: support for touch pane resizing`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Accessibility panel: Titles are now copyable (Thanks Bart!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Accessible name calculation: support self-referential aria-labelledby`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Full layout and Focus layout now use separate panes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Extensions: Add Testing Playground to known extensions`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Polypane peek: Separate logic for content and presentational images`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` A11y (app-wide): Show the correct role for presentational images`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Command bar: added close other tabs commands`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Accessibility panel: Updated accessibility ruleset`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Updated list of Google Fonts`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Improved`), ` Updated Chromium to 130.0.6723.152`)), mdx(\"p\", null, mdx(\"strong\", {\n    parentName: \"p\"\n  }, `Fixes`)), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Favicon from previous page applying when current page has no favicon of its own`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Logic for when social media previews show the og image`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Image tooltips now correctly show warnings for missing alt text`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Color jump to hue 0 when dragging color to grayscal for ruler color`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Incorrect rendering of pages due to outdated Chromium flags`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Connection errors now clear web vitals and console stats`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: improve support for CSS Selectors when calculating specificity`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: updating the color of a property using a css custom property as value updates that custom property`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: pressing the chromium button now always opens the chromium devtools in the panel`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Elements panel: Faster updating of style overview after changes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Middle click to remove debug tools`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Exclude Marker.io from internal pages`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Exclude marker.io from CORS header changes`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` incorrect size for Marker.io button for focus and full layouts`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` issue where Chromium devtools would not be in dark mode`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Invisible text in options in the app settings menu dropdowns (Thanks Alex!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Detached panel icon on macOS showed a 1px open line`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Outline panel: Late-discovered focusable elements are added in the correct order (Thanks Manuel!)`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Outline panel: Show potential landmarks option is now remembers between app starts`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Tooltip for buttons would sometimes list \"undefined\"`), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"strong\", {\n    parentName: \"li\"\n  }, `Fix`), ` Icon colors in dark mode session manager (Thanks qton!)`)));\n}\n;\nMDXContent.isMDXComponent = true;","timeToRead":10,"tableOfContents":{"items":[{"url":"#true-browser-tabs","title":"True browser tabs","items":[{"url":"#search-now-also-happens-in-regular-tabs","title":"Search now also happens in regular tabs"}]},{"url":"#split-layouts","title":"Split layouts"},{"url":"#astigmatism-simulators","title":"Astigmatism simulators"},{"url":"#ui-updates","title":"UI updates","items":[{"url":"#address-bar","title":"Address bar"},{"url":"#web-security-warning","title":"Web security warning"},{"url":"#coming-ui-updates","title":"Coming UI updates"}]},{"url":"#support-for-blob-and-data-urls","title":"Support for blob: and data: URLs"},{"url":"#performance-improvements","title":"Performance improvements"},{"url":"#elements-panel-improvements","title":"Elements panel improvements","items":[{"url":"#warning-for-allunset","title":"Warning for all:unset"},{"url":"#mouse-wheel-to-increasedecrease-numbers","title":"Mouse wheel to increase/decrease numbers"},{"url":"#stylesheets-are-now-clickable","title":"Stylesheets are now clickable"},{"url":"#better-css-selector-generation","title":"Better CSS selector generation"},{"url":"#color-previews-for-inherit-and-currentcolor","title":"Color previews for inherit and currentcolor"}]},{"url":"#outline-panel-improvements","title":"Outline panel improvements","items":[{"url":"#presentational-and-content-images","title":"Presentational and content images"},{"url":"#warnings-for-repeated-accessible-names","title":"Warnings for repeated accessible names"},{"url":"#focus-order","title":"Focus order","items":[{"url":"#late-discovered-tab-order","title":"Late discovered tab order"}]}]},{"url":"#meta-panel-improvements","title":"Meta panel improvements"},{"url":"#web-vitals-updates","title":"Web vitals updates"},{"url":"#improvements-to-the-windows-platform","title":"Improvements to the Windows platform"},{"url":"#middle-mouse-click-to-drag","title":"Middle mouse click to drag"},{"url":"#notable-fixes","title":"Notable fixes","items":[{"url":"#dark-mode-devtools","title":"Dark mode devtools"},{"url":"#clean-up-of-chromium-flags","title":"Clean up of Chromium flags"},{"url":"#connection-errors","title":"Connection errors"}]},{"url":"#get-polypane-221","title":"Get Polypane 22.1"},{"url":"#happy-new-year","title":"Happy new year!"},{"url":"#polypane-2211-changelog","title":"Polypane 22.1.1 Changelog"},{"url":"#polypane-221-changelog","title":"Polypane 22.1 Changelog"}]},"excerpt":"In this last full release of 2024 we're shipping two big new features and a host of improvements and fixes. The biggest new feature is the introduction of true…","frontmatter":{"title":"Polypane 22.1: true browser tabs and a new split layout","cover":"/img/mail/icon.svg","date":"2024-12-19","updated":null},"fields":{"slug":"/blog/polypane-22-1-true-browser-tabs-and-a-new-split-layout/","date":"2024-12-18T23:00:00.000Z","ogFileName":"polypane-22-1-true-browser-tabs-and-a-new-split-layout"}}},"pageContext":{"slug":"/blog/polypane-22-1-true-browser-tabs-and-a-new-split-layout/"}},"staticQueryHashes":["4164364741","425175329"]}