<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Wed, 21 Oct 2026 20:23:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.10</generator>
	<item>
		<title>DBKit v2: Data-Aware Controls That Do the Work</title>
		<link>https://blog.xojo.com/2026/10/21/dbkit-v2-data-aware-controls-that-do-the-work/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Wed, 21 Oct 2026 20:23:41 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[DBkit]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16718</guid>

					<description><![CDATA[DBKit v2 eliminates virtually all the code required to use DBKit. Open the database. Run the query. Copy values from the row into the controls.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>DBKit v2 eliminates virtually all the code required to use DBKit. Open the database. Run the query. Copy values from the row into the controls. Copy them back when the user edits. Handle the errors. Repeat on every window or webpage; and none of it requires any code with DBKit.</p>



<p>DBKit is a set of data-aware controls for Xojo: drop a DBKit.TextField on a layout, point it at a database, table, and column, and it loads, displays, and saves the value by itself. The query code, the glue code, the error handling: gone.</p>



<p>Version 1 proved the idea. It covered the basics and saved real time. But it still left work on your plate: filling listboxes, keeping controls in sync, writing the code that moves data back and forth.</p>



<p>Version 2 finishes the job. The controls are now fully self-sufficient. In most cases there is no database code left to write at all. The CustomersWindow from the DBKit Desktop Example project has no code at all. The same is true of the CustomersPage of the DBKit Web Example.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="699" src="https://blog.xojo.com/wp-content/uploads/2026/10/CleanShot-2026-10-17-at-11.29.18-AM@2x-1024x699.png" alt="" class="wp-image-16719" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/CleanShot-2026-10-17-at-11.29.18-AM@2x-1024x699.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/CleanShot-2026-10-17-at-11.29.18-AM@2x-300x205.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/CleanShot-2026-10-17-at-11.29.18-AM@2x-768x524.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/CleanShot-2026-10-17-at-11.29.18-AM@2x.png 1404w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>DBKit.Table.</strong>&nbsp;This is an all-new control built from the ground up: it fetches only the rows it needs to display, so whether you have hundreds of rows or millions no longer matters. Rows load fast. Table replaces the old ListBox-based approach entirely, on Desktop and Web alike.</p>



<h2 class="wp-block-heading">What is new</h2>



<p><strong>DBKit.Row.</strong>&nbsp;This is the heart of v2. A Row is the object every row event hands you, and it is how you work with data everywhere in DBKit. Read and write column values by name:&nbsp;<code>row.Column("quantity")</code>. Values from related tables use qualified names:&nbsp;<code>row.Column("products.price")</code>. Columns that do not exist in the database, like calculated columns, work exactly the same way: assign them and the table picks them up. One object, one API, everywhere.</p>



<p><strong>Row events.</strong>&nbsp;v2 introduces a full set of row events covering the row&#8217;s whole lifecycle: RowDisplayed, RowLoaded, RowChanged, RowEditing, RowSaving, RowSaved, RowCreated, RowDeleted, RowUndone, and RowNotSelected. RowDisplayed fires for each row as it appears, which is where per-row customization lives, including calculated columns:</p>



<pre class="wp-block-code"><code>Sub RowDisplayed(row As DBKit.Row) Handles RowDisplayed
  row.Column("linetotal") = row.Column("quantity") * row.Column("products.price")
End Sub</code></pre>



<p><strong>Calculated columns.</strong>&nbsp;Some values do not live in the database. A line total is quantity times price. Define the column, compute it in RowDisplayed, and the table treats it like any other column, including in totals and inline editing.</p>



<p><strong>Related rows, automatically.</strong>&nbsp;Tell DBKit about your table relationships and it loads related rows on its own. You just set the TableRelationships property in the Inspector, one relationship per line:</p>



<pre class="wp-block-code"><code>invoices.customerid=customers.id</code></pre>



<p>DBKit.Table displays related columns with no extra work, and on DBKit layouts, controls bound to related-table columns load automatically too. That&nbsp;<code>products.price</code>&nbsp;in the example above comes from the related products table. No JOINs in your code.</p>



<p><strong>Inline editing.</strong>&nbsp;Mark columns editable and users can edit cells right in the table. Edits flow through the same row events, so calculated columns like that line total stay correct automatically.</p>



<p><strong>A much more powerful SearchField.</strong>&nbsp;Drop a DBKit.SearchField on a layout and users can search as they type, with no code at all. It automatically searches every displayed column whose data type matches what they enter: text matches from the beginning of the value, quotes force an exact match, &gt; and &lt; compare numbers, two periods define a range, dates work in local or ISO format, and typing a column name first searches just that column.</p>



<p><strong>Database connections without the code.</strong>&nbsp;DBKit works directly with DatabaseConnection objects. Configure the connection in the IDE for SQLite, MySQL, PostgreSQL, or ODBC, hand it to DBKit, and there is no connection code to write.</p>



<p><strong>DBKit layouts.</strong>&nbsp;DBKit.Window, DBKit.Page, and DBKit.Container are layouts with a simple idea: bind the layout to a table, and every DBKit control on it shows the current row. The layout handles loading the row, saving edits, adding and deleting rows, undo, navigating between rows, and loading related rows. You arrange controls; DBKit does the rest.</p>



<p><strong>Nearly identical on Desktop and Web.</strong>&nbsp;Everything above works the same in desktop and web apps: the same controls, the same events, the same Row object. Learn it once, use it everywhere.</p>



<h2 class="wp-block-heading">If you are coming from v1</h2>



<p>The&nbsp;<a href="https://documentation.xojo.com/topics/databases/dbkit-conversion-guide.html">conversion guide</a>&nbsp;is short, and most of it is code to delete. That is the point.</p>



<h2 class="wp-block-heading">Try it</h2>



<p>DBKit v2 is available now. The DBKit Desktop Example and DBKit Web Example projects show it all working together: customers, invoices, and invoice items, with barely any database code in sight. The customers page in the web example, which displays and edits complete customer records, contains no code at all. Not one line. And that is just the start: v2 has a lot more new features, so check out the&nbsp;<a href="https://documentation.xojo.com/versions/2026r3/topics/databases/dbkit.html">DBKit overview</a>&nbsp;and the&nbsp;<a href="https://documentation.xojo.com/versions/2026r3/api/databases/dbkit/index.html">Classes reference</a>.</p>



<p>If you&#8217;re new to DBKit, try out the DBKit tutorials for <a href="https://documentation.xojo.com/versions/2026r3/getting_started/tutorials/dbkit_desktop_tutorial.html">desktop</a> and <a href="https://documentation.xojo.com/versions/2026r3/getting_started/tutorials/dbkit_web_tutorial.html">web</a>.</p>



<p><em>Geoff Perlman is the Founder and CEO of Xojo. When he’s not leading the Xojo team he can be found playing drums in Austin, Texas and spending time with his family.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>WinUI Support Moves to Beta</title>
		<link>https://blog.xojo.com/2026/10/20/winui-support-moves-to-beta/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:53:54 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[2026r3]]></category>
		<category><![CDATA[WinUI]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16648</guid>

					<description><![CDATA[We&#8217;ve been making steady progress on our WinUI support for Windows, and we&#8217;re excited to announce that it has now moved from&#160;Experimental to Beta in&#8230;]]></description>
										<content:encoded><![CDATA[
<p>We&#8217;ve been making steady progress on our WinUI support for Windows, and we&#8217;re excited to announce that it has now moved from&nbsp;<strong>Experimental to Beta</strong> in Xojo 2026r3.</p>



<p>There&#8217;s still work to be done, but WinUI has reached an important milestone. We&#8217;re encouraging developers to start testing their existing applications with WinUI and, most importantly, to let us know when you encounter something that doesn&#8217;t work as expected.</p>



<h2 class="wp-block-heading">Menus and Contextual Menus</h2>



<p>One of the biggest additions in this release (Xojo 2026r3) is support for WinUI based Menus and Contextual Menus.</p>



<p>Menus are an essential part of many desktop applications, and bringing them to WinUI makes it possible to build more complete, native-feeling Windows applications with Xojo.</p>



<h2 class="wp-block-heading">Symbol Support</h2>



<p>We&#8217;ve also added support for symbols to a variety of controls, including <code>DesktopPopupMenu</code> and <code>Menus</code>.</p>



<p>Symbols provide a convenient way to add familiar visual indicators and icons to your application&#8217;s interface while taking advantage of the system&#8217;s available symbol resources. This gives you another way to create modern Windows interfaces without having to manage and distribute every image yourself. Note that Symbol support is only available for WinUI, Linux and macOS.</p>



<h2 class="wp-block-heading">Picture.SystemImage&nbsp;Comes to Desktop</h2>



<p>Originally available for iOS projects,&nbsp;<code>Picture.SystemImage</code>&nbsp;is now available on desktop as well. This provides a simple way to access system-provided images and symbols from your Xojo applications.</p>



<p>The list of supported symbols can be found here:</p>



<ul class="wp-block-list">
<li>Windows:&nbsp;<a href="https://learn.microsoft.com/en-us/windows/apps/design/iconography/segoe-fluent-icons-font" target="_blank" rel="noreferrer noopener">https://learn.microsoft.com/en-us/windows/apps/design/iconography/segoe-fluent-icons-font</a></li>



<li>Linux:&nbsp;<a href="https://specifications.freedesktop.org/icon-naming" target="_blank" rel="noreferrer noopener">https://specifications.freedesktop.org/icon-naming</a></li>



<li>macOS:&nbsp;<a href="https://developer.apple.com/design/human-interface-guidelines/sf-symbols" target="_blank" rel="noreferrer noopener">https://developer.apple.com/design/human-interface-guidelines/sf-symbols</a></li>
</ul>



<p>On Windows, symbols are loaded from the Segoe Fluent Icons font (on Windows 10 they are loaded from the Segoe MDL2 Assets), so this feature is supported on both WinUI and non-WinUI Windows targets.</p>



<h2 class="wp-block-heading">Designed with WinUI in Mind</h2>



<p>As we add new functionality and controls, we&#8217;re designing with modern desktop platforms like WinUI in mind from the start. This means not only adding WinUI support to existing controls, but also improving the overall desktop experience where we can.</p>



<p>For example, our new <code><a href="https://documentation.xojo.com/api/user_interface/desktop/desktoptable.html" target="_blank" rel="noreferrer noopener">DesktopTable</a></code> provides a much better WinUI look and feel than the older <code>DesktopListBox</code> control, giving you a more modern foundation for displaying tabular data.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="810" height="701" src="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIHierarchical.png" alt="" class="wp-image-16672" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIHierarchical.png 810w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUIHierarchical-300x260.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUIHierarchical-768x665.png 768w" sizes="(max-width: 810px) 100vw, 810px" /></figure>



<figure class="wp-block-image size-large"><img decoding="async" width="934" height="677" src="https://blog.xojo.com/wp-content/uploads/2026/10/WinUITable.png" alt="" class="wp-image-16673" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/WinUITable.png 934w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUITable-300x217.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUITable-768x557.png 768w" sizes="(max-width: 934px) 100vw, 934px" /></figure>



<p>We&#8217;re also making existing controls take better advantage of the features available on modern platforms. <code><a href="https://documentation.xojo.com/api/user_interface/desktop/desktoppopupmenu.html" target="_blank" rel="noreferrer noopener">PopupMenu</a></code> now makes use of the Icons assigned to its <code>MenuItems</code>, so when building for WinUI, Linux, or macOS, those Icons automatically appear in your <code>PopupMenus</code>.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="637" height="305" src="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIPopupMenuIcons-1.png" alt="" class="wp-image-16657" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIPopupMenuIcons-1.png 637w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUIPopupMenuIcons-1-300x144.png 300w" sizes="auto, (max-width: 637px) 100vw, 637px" /></figure>



<p>Even familiar controls are getting an update. <code>SegmentedButtons</code> can now properly receive focus and be navigated between segments using the keyboard.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="904" height="253" src="https://blog.xojo.com/wp-content/uploads/2026/10/WinUISegmentedButton.png" alt="" class="wp-image-16680" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/WinUISegmentedButton.png 904w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUISegmentedButton-300x84.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUISegmentedButton-768x215.png 768w" sizes="auto, (max-width: 904px) 100vw, 904px" /></figure>



<p>&nbsp;<code>MessageBox</code>&nbsp;is now dark-mode aware when built with WinUI, allowing it to better match the appearance of your application and the user&#8217;s system settings.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="593" height="280" src="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIMessageBox.png" alt="" class="wp-image-16654" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIMessageBox.png 593w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUIMessageBox-300x142.png 300w" sizes="auto, (max-width: 593px) 100vw, 593px" /></figure>



<h2 class="wp-block-heading">From Experimental to Beta</h2>



<p>Moving WinUI support from Experimental to&nbsp;Beta&nbsp;is an important step for Xojo.</p>



<p>Beta means that we believe WinUI is ready for more developers to begin using and testing in real-world applications. It does&nbsp;not&nbsp;mean that every feature is complete or that there aren&#8217;t still issues to address. There is more work ahead, and your feedback will be an important part of getting WinUI ready for production use.</p>



<h2 class="wp-block-heading">Give WinUI a Try</h2>



<p>WinUI represents an important step forward for Xojo on Windows, and we&#8217;re excited about where it is heading.</p>



<p>If you&#8217;ve been waiting to try WinUI, <strong>now is the time</strong>. Start testing your applications, explore the new functionality, and let us know what you discover. Your feedback will help us make Xojo&#8217;s WinUI support a great foundation for building modern Windows applications.</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>I Asked Claude Code to &#8220;Make Something Wow&#8221; in Xojo Web. Here&#8217;s What It Built.</title>
		<link>https://blog.xojo.com/2026/10/20/i-asked-claude-code-to-make-something-wow-in-xojo-web-heres-what-it-built/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:53:39 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[2026r3]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Code Generation]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Xojo Web]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16664</guid>

					<description><![CDATA[Agentic Mode is one of the big additions in 2026r3. It lets Claude Code and other coding agents drive the Xojo IDE. Other posts in&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Agentic Mode is one of the big additions in 2026r3. It lets Claude Code and other coding agents drive the Xojo IDE. Other posts in this series cover things like the IDE picking up file changes from disk. In this one, I want to show you why I think <a href="https://documentation.xojo.com/getting_started/using_the_ide/agentic_mode.html" target="_blank" rel="noreferrer noopener">Agentic Mode</a> is a great fit for Xojo Web projects.</p>



<p>While I&#8217;ve been using Claude Code and I refer to it through this blog post, any other coding agent that knows how to read the AGENTS.md file should work just fine as well. We&#8217;d love to hear your AI stories and we even have <a href="https://forum.xojo.com/c/ai/92" target="_blank" rel="noreferrer noopener">a dedicated forum category for AI related posts</a>.</p>



<p>I&#8217;ve been testing Agentic Mode for a while, and one session stands out. I gave Claude Code an intentionally vague prompt, something like &#8220;make something wow, the more wow, the better&#8221;. This is what Opus 5.5 came with after 11 minutes:</p>



<figure class="wp-block-video"><video height="1322" style="aspect-ratio: 2550 / 1322;" width="2550" controls src="https://blog.xojo.com/wp-content/uploads/2026/10/globe-demo.mp4"></video></figure>



<p>Far from perfect, but still very cool!</p>



<p>It&#8217;s a mission control panel showing a 3D globe with the earthquakes of the last seven days from the USGS feed, the live position and trajectory of the International Space Station, and the day/night line. It also has a command palette. And it&#8217;s multiplayer: every web session joins as a crew member, and you can see each other appear and move around in real time. Click a crew member and you jump to their view.</p>



<p>Let me show you how we got there.</p>



<h2 class="wp-block-heading">The Setup</h2>



<p>There isn&#8217;t much to it, honestly. I created a new Xojo Web project, saved it in the plain text file format, and enabled Agentic Mode.</p>



<p>When you turn Agentic Mode on, the IDE creates an AGENTS.md file in the project folder if there isn&#8217;t one already. That file points to XOJO-CODING.md, which explains to the agent how to work with the IDE. It also links to example projects for each Xojo target, including Web.</p>



<p>There&#8217;s no MCP server involved, no plugin to install. The whole protocol is a couple of text files. When the agent wants to build and run the project, it touches a file called XojoRunProject.txt, and the IDE does the rest. If something doesn&#8217;t compile, the IDE writes the errors to XojoCompileErrors.txt so the agent can read them.</p>



<p>Claude Code read the instructions and followed them perfectly from the very first prompt.</p>



<h2 class="wp-block-heading">A JavaScript app in a Xojo shell? No, thanks</h2>



<p>The first version was impressive, but there was a catch. Claude Code built almost everything in JavaScript. It worked, but what I had was a JavaScript web app inside a Xojo Web shell, and that&#8217;s not really the point.</p>



<p>So I asked it to refine the project, using WebContainers and regular Xojo Web controls as much as possible. This is how the project looks in the IDE afterwards:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="658" src="https://blog.xojo.com/wp-content/uploads/2026/10/Captura-de-pantalla-2026-10-07-a-las-11.35.24-1024x658.png" alt="" class="wp-image-16666" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Captura-de-pantalla-2026-10-07-a-las-11.35.24-1024x658.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/Captura-de-pantalla-2026-10-07-a-las-11.35.24-300x193.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/Captura-de-pantalla-2026-10-07-a-las-11.35.24-768x493.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/Captura-de-pantalla-2026-10-07-a-las-11.35.24-1536x986.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/10/Captura-de-pantalla-2026-10-07-a-las-11.35.24.png 1872w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The page is now built from reusable pieces you&#8217;d recognize from any Xojo project: a StatsPanel, a CrewPanel with a CrewRow for each crew member, QuakeCard, LegendPanel, HintBar, a ToastStack for notifications, and so on.</p>



<p>JavaScript didn&#8217;t disappear completely, and that&#8217;s fine. It stayed where it really makes sense. GlobeControl is a WebSDKUIControl wrapping the&nbsp;<a href="https://globe.gl/" target="_blank" rel="noreferrer noopener">Globe.GL</a>&nbsp;library, which handles the 3D globe. Claude Code also wrote a few other Web SDK controls for things that really should happen in the browser, like opening the command palette when you press Cmd+K. You wouldn&#8217;t want a round trip to the server just to show a palette.</p>



<p>If you open the project, you&#8217;ll be able to follow it, and change it, like any other Xojo Web app.</p>



<p>This is my main tip if you try this yourself: tell the agent explicitly that you want a maintainable Xojo app. Otherwise, it will reach for whatever it knows best in order to please you.</p>



<h2 class="wp-block-heading">Compile, Fix, Repeat</h2>



<p>Every now and then, Claude Code wrote something that didn&#8217;t compile. A syntax error here, a wrong type there. The good news is that it saw the error in XojoCompileErrors.txt right away, fixed it and built the project again. I didn&#8217;t have to jump in a single time.</p>



<p>If you&#8217;ve ever copied and pasted code from a chat window into the IDE, then copied the compile error back into the chat, you know how much friction this removes.</p>



<h2 class="wp-block-heading">Testing in a real browser</h2>



<p>This is where it gets interesting for web projects. Code that compiles isn&#8217;t necessarily code that works, and in a web app, the only way to know for sure is to open it in a browser.</p>



<p>With the Claude in Chrome extension, Claude Code can do exactly that. You just need Google Chrome open, with the extension installed and logged in. From there, the agent runs the app, opens it in Chrome, clicks around and tests the project end to end.</p>



<p>When something looks a bit off at runtime, it takes a screenshot of the browser, tweaks the project, runs it again, and keeps looping until it looks right. Since a multiplayer feature needs more than one user, it opened several tabs to check that the crew members showed up for each other, and closed them once it didn&#8217;t need them anymore. And if the Chrome extension isn&#8217;t available for whatever reason (like using other coding agents), it can fall back to Puppeteer and drive a browser on its own.</p>



<p>In practice, this means I could describe a feature, go outside and have a coffee, and come back to find it implemented, tested and polished.</p>



<p>If you&#8217;re using other targets, feel free to ask your coding agent to embed an MCP server and use it to test the app. It will find its way to test it, no matter what. It will ask you to do a final human review on specific new features, but overall, the agent will be on autopilot most of the time.</p>



<h2 class="wp-block-heading">A few rough edges</h2>



<p>This is a promising setup, but it isn&#8217;t perfect yet.</p>



<p>If two or more coding agents try to compile different apps at the same time (and I mean the very same second), the IDE may tell you the compiler is busy, or that it couldn&#8217;t find the debug app. If you are not in front of your computer, you might find the session stuck, waiting for some human help.</p>



<p>The limitations I&#8217;ve found so far were easy to work around, by explaining to Claude Code what to do when it happens. More on that in a moment.</p>



<h2 class="wp-block-heading">Teaching your agent new tricks</h2>



<p>XOJO-CODING.md will keep improving, and we&#8217;ll keep updating the example projects to give coding agents more context. Still, sooner or later you&#8217;ll find something the agent doesn&#8217;t know how to do.</p>



<p>In my case, Claude Code didn&#8217;t know how to encode constants, or how to use folders. It was dropping every single class into the root of the project. It worked, but imagine finding your way around a big project like that.</p>



<p>If your project is under Git, this is really easy to fix. Tell the agent you&#8217;re about to create some nested folders, or a constant with special characters. It will take a look at the repository and ask you to make the change in the IDE and save the project. Once you&#8217;ve done it, tell Claude Code, and it will look at the differences to see how the IDE wrote those files. From there, you can let it refactor the project and move everything into folders.</p>



<p>Then comes the important part: ask the agent to write down what it learned in AGENTS.md. Every new session reads that file, so the next one will already know how the IDE creates project files, and how you like to work. This is also where it added the note about the busy compiler.</p>



<p>If you&#8217;re working on an existing project, it gets even easier. You won&#8217;t need to show the agent how to use folders if your project already uses them, because it will follow what&#8217;s there. The more you use it, the better it gets. And the bigger the project, the easier it is for the agent to add new features in the same way you&#8217;re already working.</p>



<h2 class="wp-block-heading">Try it yourself!</h2>



<p>You can download the Mission Control project here:</p>



<p><a href="https://blog.xojo.com/wp-content/uploads/2026/10/GlobeProjectTest.zip" target="_blank" rel="noreferrer noopener">Download GlobeProjectTest.zip</a></p>



<p>Open it with 2026r3, run it in a couple of browser windows, and watch your crew show up.</p>



<h2 class="wp-block-heading">Working on Several Features at Once with Git Worktrees</h2>



<p>Once you get used to delegating features, you&#8217;ll start wondering why you have to wait for one to finish before starting the next. This is where Git worktrees come in.</p>



<p>A worktree lets you check out several branches of the same repository at once, each one in its own folder. Since every folder has its own copy of the project file, the Xojo IDE just sees them as different projects and opens each one separately. You can have one agent adding a new panel in one worktree, while another one fixes a bug in a second worktree, without stepping on each other&#8217;s toes.</p>



<p>When a feature is ready, review the changes and merge the branch, just like you would with work coming from any other developer on your team. Or even better, ask the agent to do the merge.</p>



<p>A few things to keep in mind. First, each web app needs its own port. If two worktrees try to run their debug apps on the same port, only the first one will start. Ask each agent to use a different debug port in its worktree, and they&#8217;ll be able to run side by side.</p>



<p>Second, commit your AGENTS.md file. That way, every worktree starts with everything your agents have learned so far, and a finding from one worktree can be merged back for the rest. Just don&#8217;t write a specific port number there, or every worktree will inherit the same one. Tell each agent which port to use when you start the session instead.</p>



<p>And third, remember the rough edge I mentioned earlier: if two agents happen to compile at the very same second, the IDE may report the compiler as busy. That&#8217;s exactly the kind of note worth adding to AGENTS.md, so your agents know to wait a moment and try again.</p>



<h2 class="wp-block-heading">Wrapping up</h2>



<p>I didn&#8217;t expect this to work as well as it did. The agent writes the code, the IDE compiles it, Chrome shows the result, and the loop keeps going until the app works. Your job moves from typing code to deciding what to build, and reviewing what comes back.</p>



<p>Learn more about using Agentic Mode in the <a href="https://documentation.xojo.com/getting_started/using_the_ide/agentic_mode.html" target="_blank" rel="noreferrer noopener">Docs</a> and in the <a href="https://documentation.xojo.com/getting_started/quickstarts/ai_quickstart.html" target="_blank" rel="noreferrer noopener">AI QuickStart</a>. I&#8217;d love to see what you build with Agentic Mode. Share some screenshots or recordings in a new forum thread, or send me a private message if you prefer.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://x.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/10/globe-demo.mp4" length="8889006" type="video/mp4" />

			</item>
		<item>
		<title>Xojo Web 2026r3: URL Routing, New Features, and Two Important Changes</title>
		<link>https://blog.xojo.com/2026/10/20/xojo-web-2026r3-url-routing-new-features-and-two-important-changes/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:53:28 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2026r3]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16660</guid>

					<description><![CDATA[2026r3 brings a bit of everything to Xojo Web: two breaking changes you&#8217;ll want to read about before updating, a new URL router, a few&#8230;]]></description>
										<content:encoded><![CDATA[
<p>2026r3 brings a bit of everything to Xojo Web: two breaking changes you&#8217;ll want to read about before updating, a new URL router, a few small additions that were long overdue, and more than 40 bug fixes.</p>



<h2 class="wp-block-heading">Breaking Changes First</h2>



<p>I&#8217;d rather start with the uncomfortable part, so nobody gets surprised after updating.</p>



<h3 class="wp-block-heading">Unhandled exceptions will now quit your app</h3>



<p>Until now, the web framework was silently swallowing unhandled exceptions, and your app kept running as if nothing had happened. Desktop projects don&#8217;t behave like that. After going back and forth on it internally, we&#8217;ve decided to treat this difference as what it really is: a bug.</p>



<p>Starting with 2026r3, a web app will quit when an exception isn&#8217;t handled, unless you&nbsp;<code>Return True</code>&nbsp;from one of the UnhandledException events.</p>



<p>There are two of them. When something goes wrong inside a session context and you aren&#8217;t catching it in code, Session.UnhandledException fires first. A database call failing after the user presses a WebButton is a typical example. If you&nbsp;<code>Return True</code>&nbsp;there, the app keeps running. If you don&#8217;t, the exception keeps bubbling up and App.UnhandledException fires.</p>



<p>App.UnhandledException is your app&#8217;s last chance, and this is where the behavior changes. If you don&#8217;t&nbsp;<code>Return True</code>there, the app will print the stack trace, hoping it ends up logged somewhere, and quit.</p>



<p>If you really want things to work like before, add a&nbsp;<code>Return True</code>&nbsp;to App.UnhandledException and you&#8217;re done. But I&#8217;d encourage you to use this as an excuse to start paying attention to those exceptions. They are trying to tell you something. At the 2024 MBS Conference, Xojo MVP Jeremy Leroy gave a talk about tracking exceptions with Sentry, and I can&#8217;t recommend it enough:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="MBS Xojo Conference 2024 - Managing exceptions like a pro" width="500" height="281" src="https://www.youtube.com/embed/mxekiMAAzTA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h3 class="wp-block-heading">Positioning controls by code</h3>



<p>The second change comes from a series of bug fixes around positioning controls programmatically. The web framework had some issues here that made dynamic interfaces more painful than they should have been, and many of you ended up writing workarounds.</p>



<p>Web projects now place controls much closer to how Desktop projects do. The catch is that a workaround in your code may now be compensating for a problem that no longer exists. If you position controls by code, check your layouts after updating and remove the workarounds you don&#8217;t need anymore.</p>



<p>We try really hard to avoid breaking changes. In these two cases, we believe it&#8217;s the right call in the long run.</p>



<h2 class="wp-block-heading">URL Router</h2>



<p>On to the new stuff. The URL router is another piece of the puzzle on our way to SEO friendly web apps. Until now, if you wanted nice URLs, you had to parse them yourself in App.HandleURL, probably fighting with regular expressions along the way.</p>



<p>2026r3 adds a new <a href="https://documentation.xojo.com/api/web/webapplication.html#webapplication-addurlroute" target="_blank" rel="noreferrer noopener">WebApplication.AddURLRoute</a> method. Imagine you are building a blogging system with URLs like this one:</p>



<p><code>/2026/06/25/build-a-threaded-find-in-files-solution/</code></p>



<p>You&#8217;ll need a WebPage to display a single post. Let&#8217;s call it BlogPostWebPage. With that in place, this one-liner in App.Opening is all it takes:</p>



<pre class="wp-block-code"><code>AddURLRoute("/&lt;year:integer&gt;/&lt;month:integer&gt;/&lt;day:integer&gt;/&lt;slug:string&gt;/", TypeOf BlogPostWebPage)</code></pre>



<p>Two things are happening here. The obvious one: when a request matches the route, Xojo Web creates a new BlogPostWebPage instance and shows it. Notice the type next to each parameter name, too. A URL like&nbsp;<code>/hello/06/25/some-post/</code>&nbsp;won&#8217;t match, because &#8220;hello&#8221; isn&#8217;t an integer.</p>



<p>The second one is more subtle, and it&#8217;s where this gets handy. Since the route defines named parameters, you can read them from the BlogPostWebPage.Opening event using Session.URLNamedParameter:</p>



<pre class="wp-block-code"><code>Self.Title = Session.URLNamedParameter("slug")</code></pre>



<p>From there, it&#8217;s just a matter of using the slug to query your database and fill the page with the right post.</p>



<p>This is the first version of the router, and we&#8217;re looking forward to your feedback. If you find something we missed, please open a Bug Report or a Feature Request.</p>



<h2 class="wp-block-heading">WebCanvas.DrawControlInLayoutEditor</h2>



<p>Xojo targets keep borrowing ideas from each other. In the previous release, DesktopCanvas got a new DrawControlInLayoutEditor event, heavily inspired by WebSDKUIControl.DrawControlInLayoutEditor. Now <a href="https://documentation.xojo.com/api/user_interface/web/webcanvas.html#webcanvas" target="_blank" rel="noreferrer noopener">WebCanvas</a> supports it as well, so your canvas-based controls can show a preview of themselves in the Layout Editor instead of an empty box.</p>



<h2 class="wp-block-heading">WebFileUploader Improvements</h2>



<p>Until now, if a user picked the wrong file, the only thing you could offer was clearing the whole uploader and asking them to select everything again. That&#8217;s not great when they&#8217;ve picked ten files and only one of them was wrong.</p>



<p><a href="https://documentation.xojo.com/api/user_interface/web/webfileuploader.html#webfileuploader" target="_blank" rel="noreferrer noopener">WebFileUploader</a> in 2026r3 adds the FileNameAt and RemoveFileAt methods, plus the FileCount and LastFileIndex read-only computed properties. With them, you can let your users change their mind and remove individual files before uploading.</p>



<h2 class="wp-block-heading">WebRectangle.Pressed Event</h2>



<p>Last, but not least, <a href="https://documentation.xojo.com/api/user_interface/web/webrectangle.html#webrectangle" target="_blank" rel="noreferrer noopener">WebRectangle</a> finally has a Pressed event. WebRectangles are commonly used to group other controls, like a card with a title, a picture and a couple of labels, so making the whole group clickable made a lot of sense. Child controls can still have their own Pressed handlers. If none of them handles the press, it keeps bubbling up until it reaches the parent WebRectangle.</p>



<h2 class="wp-block-heading">Bug Fixes &amp; Wrapping Up</h2>



<p>The rest of the web side of this release is mostly bug fixes, more than 40 of them. As boring as that might sound, if just one of them makes your day to day a bit easier, it was worth it.</p>



<p>As usual, make sure to read the full release notes, because there&#8217;s much more in there than fits in a blog post. And thank you for taking the time to read this, test the betas, report bugs, send feature requests and renew your license. It all helps more than you might think.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://x.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>New Features for the iOS Framework</title>
		<link>https://blog.xojo.com/2026/10/20/new-features-for-the-ios-framework/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:53:15 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[2026r3]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16490</guid>

					<description><![CDATA[Xojo 2026r3 introduces a bunch of new features and improvements to make your iOS apps shine even more. With updates to the recently added MobileMenuItem&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2026r3 introduces a bunch of new features and improvements to make your iOS apps shine even more. With updates to the recently added <a href="#MobilePopupMenu" target="_blank" rel="noreferrer noopener">MobileMenuItem and MobilePopupMenu</a> classes, the <a href="#MobileScreen" target="_blank" rel="noreferrer noopener">MobileScreen</a>, and the addition of an independent <a href="#MobileSearchField" target="_blank" rel="noreferrer noopener">MobileSearch</a> control, you&#8217;ll be able to do more. Xojo 2026r3 also adds the ability to <a href="#mobiledocumentpicker" target="_blank" rel="noreferrer noopener">open documents</a> outside the app sandbox, <a href="#MobilePrinterPicker" target="_blank" rel="noreferrer noopener">print most common file formats</a> using compatible AirPrint printers, <a href="#MobileDocumentViewer" target="_blank" rel="noreferrer noopener">view, edit and save</a> the most common file types (including Microsoft Office Word and Excel), and support <a href="#DynamicType" target="_blank" rel="noreferrer noopener">Dynamic Type</a> on MobileLabel, MobileTextField and MobileTextArea. Continue reading to find out how you can implement these!</p>



<span id="more-16490"></span>



<h3 class="wp-block-heading" id="MobileDocumentPicker">MobileDocumentPicker: Beyond the Sandbox</h3>



<p>Starting with Xojo 2026r3, your iOS apps are able to open and even save files outside the usual folders related to the app sandbox. Using the new <a href="https://documentation.xojo.com/api/user_interface/mobile/mobileprintpicker.html" target="_blank" rel="noreferrer noopener">MobileDocumentPicker</a> class, it is now possible to open any available PDF document saved on the device (or even in iCloud) and display it using the MobilePDFViewer.</p>



<figure class="wp-block-video"><video controls src="https://blog.xojo.com/wp-content/uploads/2026/09/DocumentPicker.mp4"></video></figure>



<p>This also applies when saving files. For example, any PDF documents created using the PDFDocument class, any image, text or any other kind of document file you create in your iOS app can be saved for public availability outside of the sandboxed folders. Once saved, these documents can be opened by other apps installed on the same device, or even automatically synced via iCloud.</p>



<p>It is not necessary to enable any capability in your iOS project, or add entitlements or additional entries to the app&#8217;s .plist file, just use MobileDocumentPicker.Open and MobileDocumentPicker.Save methods.</p>



<h3 class="wp-block-heading" id="MobilePrinterPicker">Printing Arrives to iOS</h3>



<p>In addition to the MobileDocumentPicker, we also added the <a href="https://documentation.xojo.com/api/user_interface/mobile/mobileprintpicker.html" target="_blank" rel="noreferrer noopener">MobilePrinterPicker</a> starting with Xojo 2026r3. This control allows your app to print any of the most common file formats (for example PDF, images, text, html, .Pages and .Numbers) to any printer available on the network that is compatible with the AirPrint technology.</p>



<figure class="wp-block-video"><video controls src="https://blog.xojo.com/wp-content/uploads/2026/09/DocumentPrinter.mp4"></video></figure>



<p>You only need to call the MobilePrinterPicker.Print method, passing along the FolderItem whose content will be printed. The iOS modal dialog will offer options to select the target printer and all of the print settings for that printer, from the page size, to the range of pages to print, enabling duplex printing, color printing, etc.&nbsp;</p>



<h3 class="wp-block-heading" id="MobileDocumentViewer">Viewing Documents</h3>



<p>Now that we are able to access documents beyond the app sandbox and print them, it would be great to have the ability to display the most common document formats in your iOS apps &#8211; plus allow users to edit and save their changes! That is exactly what the new <a href="https://documentation.xojo.com/api/user_interface/mobile/mobiledocumentviewer.html" target="_blank" rel="noreferrer noopener">MobileDocumentViewer</a> does.</p>



<p>The MobileDocumentViewer allows your iOS app to view the following file formats:</p>



<ul class="wp-block-list">
<li><strong>iWork documents</strong>.</li>



<li><strong>Microsoft Office documents</strong>.</li>



<li><strong>Rich text format, or RTF, documents</strong>.</li>



<li><strong>PDF files</strong>.</li>



<li><strong>Images</strong>.</li>



<li><strong>Text files</strong> with a uniform type identifier that conforms to the public.text type.</li>



<li><strong>Comma-separated values, or CSV</strong>, files.</li>



<li><strong>Video</strong> files.</li>
</ul>



<p>And edit (and save) the changes made by the user in the following ones:</p>



<ul class="wp-block-list">
<li><strong>PDF Files</strong> (signing, drawing, rotating pages, adding or deleting pages, adding pages from scan, etc.)</li>



<li><strong>Images</strong> (drawing, cropping, etc.)</li>



<li><strong>Video files</strong> (trimming)</li>
</ul>



<p>You only need to drag the MobileDocumentViewer from the Library into the Tray area of the Screen where it is intended to be used. Calling the Show method on the instance will open the modal view to let users view and navigate among the received array of FolderItem instances of the documents to be shown.</p>



<figure class="wp-block-video"><video controls src="https://blog.xojo.com/wp-content/uploads/2026/09/Screen-Recording-2026-09-17-at-12.28.17.mp4"></video></figure>



<p>To react to the changes made by the user in the compatible document file formats, there is the DocumentSaved event handler, which (once implemented) receives the FolderItem of the document that has been modified.</p>



<h3 class="wp-block-heading" id="MobileSearchField">MobileSearchField</h3>



<p>Available on Desktop and Web targets, the <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilesearchfield.html" target="_blank" rel="noreferrer noopener">MobileSearchField</a> has been added to the Mobile target.</p>



<p>In previous releases, it was possible to do a search or filter data in iOS apps using the iOSMobileTable control. However, there are situations where you may need more than one search control on the same iOS screen; and in some cases, you don&#8217;t need the search to display matching data in an iOSMobileTable.</p>



<p>For those scenarios, you can now add and use as many MobileSearchField controls as your app requires.</p>



<figure class="wp-block-video"><video autoplay controls loop src="https://blog.xojo.com/wp-content/uploads/2026/08/MobileSearchField.mp4"></video></figure>



<p>When using this control, you can not only set the default Hint or Text property values, but also enable a scope bar and set the title names for each scope. Think of the scope bar as a way to let users (and your app) filter results not only by the typed text, but also by a specific category, for example.</p>



<p>The scope bar can be enabled or disabled at runtime via code, as well as each title name displayed by the scope bar.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="588" height="276" src="https://blog.xojo.com/wp-content/uploads/2026/08/SearchScopes.png" alt="" class="wp-image-16492" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/SearchScopes.png 588w, https://blog.xojo.com/wp-content/uploads/2026/08/SearchScopes-300x141.png 300w" sizes="auto, (max-width: 588px) 100vw, 588px" /></figure>
</div>


<p>The main event handlers that you will probably want to implement for this control are:</p>



<ul class="wp-block-list">
<li><strong>SearchPressed()</strong>. Fires when the user taps on the &#8220;Done&#8221; button on the device soft keyboard</li>



<li><strong>ScopeChanged(index As Integer)</strong>. Fires when the user changes the current scope in the scope bar (if enabled for the search field instance</li>



<li><strong>TextChanged()</strong>. Fires every time there is a change in the text field of the SearchField control</li>
</ul>



<h3 class="wp-block-heading" id="iOSMobileTable">iOSMobileTable SearchField</h3>



<p>We also improved how the already available search field for <a href="https://documentation.xojo.com/api/ios/iosmobiletable.html#iosmobiletable" target="_blank" rel="noreferrer noopener">iOSMobileTable</a> behaves, especially when the iOS app is run on iOS 26+.</p>



<ul class="wp-block-list">
<li>If the app uses a MobileTabBar or MobileToolbar, then the associated iOSMobileTable search field will move automatically to the navigation bar section.</li>



<li>When the search field is in the navigation bar section, it will be collapsed by default (displaying only the loupe icon), so it doesn&#8217;t take up extra space on the app screen when the user isn&#8217;t searching. Tapping on the loupe icon will expand the search field for the table, letting the user type. As soon as the search field loses the focus, it will collapse again as the loupe icon.</li>
</ul>



<figure class="wp-block-video"><video autoplay controls loop src="https://blog.xojo.com/wp-content/uploads/2026/08/TableSearchiOS.mp4"></video></figure>



<h3 class="wp-block-heading" id="MobilePopupMenu">MobileMenuItem and MobilePopupMenu Improvements</h3>



<p>Both MobileMenuItem class and MobilePopupMenu were introduced in Xojo 2026r2. In 2026r3, they received a number of improvements.</p>



<h4 class="wp-block-heading">MobileMenuItem</h4>



<ul class="wp-block-list">
<li><strong>Icon property</strong>. It is now possible to use Picture.SystemImage or a Picture directly to assign an icon to each item.</li>



<li><strong>Symbol</strong> <strong>property</strong>. You can now assign an SF Symbol name to this property and it will be used as the item&#8217;s image. You can also assign multiple symbol names separated by semicolons. The first one found will be the one used.<br>An advantage of using Symbol instead of Icon is that it will generate the assigned image at the expected size.</li>



<li><strong>AllowMulticolorSymbol</strong> <strong>property</strong>. When this property is set to True, the assigned symbol will use the Multicolor rendering mode instead of Monochrome.</li>



<li><strong>Separator</strong>. It is now possible to add separators to a menu using the same syntax as on Desktop: New MobileMenuItem(&#8220;-&#8220;).</li>



<li><strong>IntegratedPalette</strong> <strong>display mode</strong>. Starting with Xojo 2026r3, we added the IntegratedPalette to MobileMenuItem.RenderingModes. When used as the display mode on a submenu, it will be integrated into the main menu it is attached to using an horizontal format. This allows creating the kind of menus commonly found in many iOS apps.</li>
</ul>



<p>For example, the following code:</p>



<pre class="wp-block-code"><code>Var horizontalSubmenu As New MobileMenuItem("")
Var firstSubmenu As New MobileMenuItem("Pencil")
firstSubmenu.Tag = "Pencil"
firstSubmenu.Symbol = "pencil"

Var secondSubmenu As New MobileMenuItem("Eraser")
secondSubmenu.Symbol = "eraser"
secondSubmenu.Tag = "Eraser"

Var thirdSubmenu As New MobileMenuItem("Lasso")
thirdSubmenu.Symbol = "lasso"
thirdSubmenu.Tag = "Lasso"

horizontalSubmenu.AddMenu(firstSubmenu)
horizontalSubmenu.AddMenu(secondSubmenu)
horizontalSubmenu.AddMenu(thirdSubmenu)
horizontalSubmenu.DisplayMode = MobileMenuItem.DisplayModes.IntegratedPalette

Var mainMenu As New MobileMenuItem
mainMenu.AddMenu(horizontalSubmenu)

Var firstMain As New MobileMenuItem("Triangle")
firstMain.Symbol = "righttriangle"
firstMain.Tag = "Triangle"
Var secondmain As New MobileMenuItem("Viewer")
secondmain.Symbol = "plus.viewfinder"
secondmain.Tag = "Viewer"

mainMenu.AddMenu(firstMain)
mainMenu.AddMenu(secondmain)
mainMenu.AddMenu(New MobileMenuItem("-"))

Var thirdMain As New MobileMenuItem("Delete")
thirdMain.Symbol = "trash"
thirdMain.Tag = "Delete"
thirdMain.Destructive = True
mainMenu.AddMenu(thirdMain)

Me.Menu = mainMenu
Me.DisplayMenuAsAction = True</code></pre>



<p>will create this menu when displayed:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="578" height="400" src="https://blog.xojo.com/wp-content/uploads/2026/08/Screenshot-2026-08-27-at-15.26.02.png" alt="" class="wp-image-16494" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/Screenshot-2026-08-27-at-15.26.02.png 578w, https://blog.xojo.com/wp-content/uploads/2026/08/Screenshot-2026-08-27-at-15.26.02-300x208.png 300w" sizes="auto, (max-width: 578px) 100vw, 578px" /></figure>
</div>


<h3 class="wp-block-heading">MobilePopupMenu</h3>



<p>On the MobilePopupMenu side, it received several fixes and improvements. Also, since MobileMenuItem can now handle separators, MobilePopupMenu now includes the AddSeparator method already available in the DesktopPopupMenu counterpart.</p>



<p>And because MobileMenuItem can now handle an Icon or Symbol, you can expect these to be supported when the items are displayed in the popup menu control.</p>



<figure class="wp-block-video"><video autoplay controls loop src="https://blog.xojo.com/wp-content/uploads/2026/08/MobilePopupMenu.mp4"></video></figure>



<h3 class="wp-block-heading">Symbols Everywhere!</h3>



<p>The Symbol and AllowMulticolorSymbol properties were not only added to <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilemenuitem.html#mobilemenuitem">MobileMenuItem</a>, starting with Xojo 2026r3, you will be able to set them for the following controls and classes on iOS:</p>



<ul class="wp-block-list">
<li><a href="https://documentation.xojo.com/api/user_interface/mobile/mobilebutton.html#mobilebutton" target="_blank" rel="noreferrer noopener">MobileButton</a></li>



<li><a href="https://documentation.xojo.com/api/user_interface/mobile/mobiletoolbarbutton.html#mobiletoolbarbutton" target="_blank" rel="noreferrer noopener">MobileToolbarButton</a></li>



<li><a href="https://documentation.xojo.com/api/user_interface/mobile/mobilesegmentedbutton.html#mobilesegmentedbutton" target="_blank" rel="noreferrer noopener">MobileSegmentedButton</a></li>



<li><a href="https://documentation.xojo.com/api/ios/iosmobiletablerowaction.html#iosmobiletablerowaction" target="_blank" rel="noreferrer noopener">iOSMobileTableRowAction</a></li>
</ul>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1179" height="2556" src="https://blog.xojo.com/wp-content/uploads/2026/08/Symbols-Action-Row.png" alt="" class="wp-image-16504" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/Symbols-Action-Row.png 1179w, https://blog.xojo.com/wp-content/uploads/2026/08/Symbols-Action-Row-138x300.png 138w, https://blog.xojo.com/wp-content/uploads/2026/08/Symbols-Action-Row-472x1024.png 472w, https://blog.xojo.com/wp-content/uploads/2026/08/Symbols-Action-Row-768x1665.png 768w, https://blog.xojo.com/wp-content/uploads/2026/08/Symbols-Action-Row-709x1536.png 709w, https://blog.xojo.com/wp-content/uploads/2026/08/Symbols-Action-Row-945x2048.png 945w" sizes="auto, (max-width: 1179px) 100vw, 1179px" /></figure>



<p>That means you can now create more visual, modern (and colorful) UI designs for your iOS apps.</p>



<h3 class="wp-block-heading" id="MobileScreen">MobileScreen</h3>



<p>A couple of interesting improvements in this area:</p>



<ul class="wp-block-list">
<li><strong>MobileScreen.Show(makeCurrent As Boolean)</strong> &#8211; When the passed parameter is set to True, the new screen will substitute the current one without changing or being added to the app navigation stack. If the value is set to False, it will behave like the regular Show method when no parent screen is provided.</li>
</ul>



<figure class="wp-block-video"><video autoplay controls loop src="https://blog.xojo.com/wp-content/uploads/2026/08/mobileModalScreen.mp4"></video></figure>



<ul class="wp-block-list">
<li><strong>MobileScreen.ShowModal</strong> &#8211; We added a couple more parameters at the end of the method signature. The first one allows you to set the size of the modal to be shown (Medium, Large, Resizable) using the new ModalPresentationSizes enum. The last parameter, when set to True, will display a grabber widget at the top of the modal so the user better knows they can drag, especially if the modal is set to ModalPresentationSizes.Resizable.</li>
</ul>



<h3 class="wp-block-heading" id="DynamicType">The Arrival of Dynamic Type</h3>



<p>Dynamic Type is an Apple iOS feature that allows the user to set a preferred text size for apps that support it. That way, users can adjust the text shown by labels, text fields, text areas or even the captions on buttons to better fit their visual needs.</p>



<p>You can find this setting under Settings &gt; Accessibility &gt; Display &amp; Text Size &gt; Larger Text. From here, users can choose their preferred text size, and can also enable the Larger Accessibility Sizes switch if they need even bigger text than the standard range offers.</p>



<p>Starting with Xojo 2026r3, we&#8217;ve added a new Boolean property called UseAccessibilityFontSize to the following classes:</p>



<ul class="wp-block-list">
<li><a href="https://documentation.xojo.com/api/user_interface/mobile/mobilebutton.html#mobilebutton" target="_blank" rel="noreferrer noopener">MobileButton</a></li>



<li><a href="https://documentation.xojo.com/api/user_interface/mobile/mobilelabel.html#mobilelabel" target="_blank" rel="noreferrer noopener">MobileLabel</a></li>



<li><a href="https://documentation.xojo.com/api/user_interface/mobile/mobiletextarea.html#mobiletextarea" target="_blank" rel="noreferrer noopener">MobileTextArea</a></li>



<li><a href="https://documentation.xojo.com/api/user_interface/mobile/mobiletextfield.html#mobiletextfield" target="_blank" rel="noreferrer noopener">MobileTextField</a></li>
</ul>



<p>When this property is set to True, the controls will automatically display text at the size the user configured in their iOS Accessibility settings. Note that enabling this property forces the control to use the system font, since Dynamic Type only works with system fonts.</p>



<figure class="wp-block-video"><video autoplay controls loop src="https://blog.xojo.com/wp-content/uploads/2026/08/DynamicText.mp4"></video></figure>



<h4 class="wp-block-heading">Reacting to Dynamic Type Changes</h4>



<p>If you want to use some variations of the system font (for example, Bold), or manually react to user changes for the Dynamic Type settings, then you will find the new AccesibilityFontSizeChanged event handler on the <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilescreen.html#mobilescreen" target="_blank" rel="noreferrer noopener">MobileScreen</a> class useful.</p>



<p>In addition, we added the shared method AccessibilityFontSize to the Font class, so you can retrieve the current Dynamic Type font size set by the user and react accordingly. For example, if you keep the UseAccessibilityFontSize set to False for your controls, this value lets your code apply any needed UI changes.</p>



<h3 class="wp-block-heading">MobileTextArea and MobileTextField</h3>



<p>These controls also received a small but useful feature: when you need to dismiss the keyboard and there is no suitable UI area to tap, the text field or text area can clear its focus and close the keyboard itself.</p>



<figure class="wp-block-video"><video autoplay controls loop src="https://blog.xojo.com/wp-content/uploads/2026/08/MobileTextFieldDone.mp4"></video></figure>



<p>Now, the new Boolean AllowDoneButton property can be set to True to add a &#8220;Done&#8221; button in the associated view of the keyboard itself. This way, once the user has finished typing in the control, they only need to tap the &#8220;Done&#8221; button in the keyboard for it to be closed and the control focus to be cleared.</p>



<h3 class="wp-block-heading">Summary</h3>



<p>We can&#8217;t wait to see how the new features will make their way into your iOS apps. As you&#8217;ve seen, there are also a good number of improvements you can use to update your existing apps and delight your users even more. Share your comments and creations on the <a href="https://forum.xojo.com" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/09/DocumentPicker.mp4" length="627349" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/09/DocumentPrinter.mp4" length="933315" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/09/Screen-Recording-2026-09-17-at-12.28.17.mp4" length="1732213" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/08/MobileSearchField.mp4" length="985731" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/08/TableSearchiOS.mp4" length="97925" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/08/MobilePopupMenu.mp4" length="159044" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/08/mobileModalScreen.mp4" length="1679597" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/08/DynamicText.mp4" length="564798" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/08/MobileTextFieldDone.mp4" length="184322" type="video/mp4" />

			</item>
		<item>
		<title>Use AI Coding Agents with Xojo Agentic Mode</title>
		<link>https://blog.xojo.com/2026/10/20/use-ai-coding-agents-with-xojo-agentic-mode/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:52:47 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[2026r3]]></category>
		<category><![CDATA[Agentic Mode]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Code Generation]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16563</guid>

					<description><![CDATA[In Xojo 2026r3, the new Agentic Mode makes it easy to work with your favorite coding agent to help make apps. For about a year&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In Xojo 2026r3, the new Agentic Mode makes it easy to work with your favorite coding agent to help make apps.</p>



<p>For about a year now, Jade, Xojo&#8217;s built-in AI chat assistant, has been able to help you with coding questions, code reviews, bug fixes and focused code generation. Agentic Mode takes things to an entirely new level.</p>



<p>Coding agents are separate products that are able to do interactive code generation directly on project files. Popular coding agents include <a href="https://claude.com/product/claude-code" target="_blank" rel="noreferrer noopener">Claude Code</a> and <a href="https://chatgpt.com/codex" target="_blank" rel="noreferrer noopener">ChatGPT Codex</a>, but there are many others. I&#8217;ve personally found that Claude Code works well from inside the Claude desktop app.</p>



<p>Although most of the AI companies let you use their chat products for free, you usually have to purchase a plan to get access to the coding agent. Of course, there are some free plans around and you could even install a local LLM and an open-source agent if you wanted. Since the coding agent works directly on the project files, any coding agent will work with Agentic Mode in Xojo.</p>



<h2 class="wp-block-heading">What is Agentic Mode?</h2>



<p>For Xojo, <a href="https://documentation.xojo.com/getting_started/using_the_ide/agentic_mode.html" target="_blank" rel="noreferrer noopener">Agentic Mode</a> is a setting in the File menu that provides some guidance to the coding agent and allows the agent to request to run Xojo projects and get back compilation errors. It also tells Xojo to regularly reload files in the project as they are changed.</p>



<p>To use Agentic Mode you first have to save the project to text format. After doing this, you can select File-&gt;Agentic Mode to turn it on. This displays the Messages panel so you can see information about project files that get reloaded.</p>



<p>You can now go to your coding agent and add the folder containing your text project as a work folder. After doing that you can type prompts to the coding agent and watch it do its thing. The agent will think, change files, request to run the project, review any compilation errors and generally just chug along until it has finished the task you gave it. While this is all happening, you&#8217;ll be able to watch project items change in Xojo and even see the debug app start and stop.</p>



<p>Each coding agent works similarly, but they have their differences as well. They are also all highly capable and will learn new features as they work through your project and your prompts.</p>



<h2 class="wp-block-heading">Agentic Mode in Action</h2>



<p>To show you how Agentic Mode works, we will do two quick examples.</p>



<p>This first example creates an empty project and asks the coding agent to create an app.</p>



<p>Start Xojo, from the Project Chooser select Desktop and give it the name StockTicker. Check the &#8220;for AI (Agentic Mode)&#8221; checkbox and click Create. You will be immediately prompted to choose a folder. Select a folder and Xojo will automatically create a new folder in that folder with the name StockTicker, save the project as text into the folder and turn on Agentic Mode.</p>



<p>You can now open your coding agent (I&#8217;m using Claude Code for this example) and start a new session. Add the StockTicker folder as a working directory and select your preferred model (I used Sonnet 5.5/Medium). Now enter the prompt to create the app. I used this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Create a stock ticker app. By default have it show some common stocks in the S&amp;P 500, but allow the user to enter their own stock tickers. Use a web service to get values for stocks in common indices. Display the stock prices in a list.</p>
</blockquote>



<p>Here is my initial setup with Xojo and Claude Code both open:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="446" src="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.09.06@2x-1024x446.png" alt="" class="wp-image-16585" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.09.06@2x-1024x446.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.09.06@2x-300x131.png 300w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.09.06@2x-768x334.png 768w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.09.06@2x-1536x668.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.09.06@2x-2048x891.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Claude Code chugged for a couple minutes and when it was done it had created this app:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="750" src="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.14.19@2x-1024x750.png" alt="" class="wp-image-16586" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.14.19@2x-1024x750.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.14.19@2x-300x220.png 300w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.14.19@2x-768x562.png 768w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.14.19@2x-1536x1125.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-14.14.19@2x.png 1584w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Here is a (sped-up) video of the overall process:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Using Xojo&#039;s Agentic Mode - ToDo Claude Example" width="500" height="281" src="https://www.youtube.com/embed/dRDzpOHi9Bw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>The next example modifies an existing project. In this case, we will use the ToDo project that is included as a Xojo example. Using the Project Chooser, open the Desktop ToDo example and save it as a text project to a folder called DesktopToDo. Turn on Agentic Mode (File-&gt;Agentic Mode).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="663" src="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.42.29@2x-1024x663.png" alt="" class="wp-image-16574" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.42.29@2x-1024x663.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.42.29@2x-300x194.png 300w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.42.29@2x-768x497.png 768w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.42.29@2x-1536x994.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.42.29@2x-2048x1325.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Open your coding agent, add the DesktopToDo folder and give it your prompt. I used this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Please review and improve this project. Perhaps make the UI a little snazzier and clean up code as necessary.</p>
</blockquote>



<p>The ToDo app UI went from looking like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="711" src="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.45.09@2x-1024x711.png" alt="" class="wp-image-16575" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.45.09@2x-1024x711.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.45.09@2x-300x208.png 300w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.45.09@2x-768x533.png 768w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.45.09@2x-1536x1067.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.45.09@2x-2048x1422.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>To this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="713" src="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.50.08@2x-1024x713.png" alt="" class="wp-image-16576" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.50.08@2x-1024x713.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.50.08@2x-300x209.png 300w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.50.08@2x-768x535.png 768w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.50.08@2x-1536x1069.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-29-at-11.50.08@2x-2048x1426.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>It took less than two minutes for Claude Code to make these changes, fixing some of its own compile errors along the way. There were also code changes, of course. It even offered to make additional changes, such as add the ability to save the ToDo items between app launches.</p>



<p>Here is a (sped up) video of Claude Code working on this with Xojo:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Using Xojo&#039;s Agentic Mode - ToDo Claude Example" width="500" height="281" src="https://www.youtube.com/embed/dRDzpOHi9Bw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>Keep in mind that because these AI systems are non-deterministic you will get wildly different results from the same prompt. For example, in different tests with this same example and prompt, I got a changed ToDo app UI that was more colorful and had automatic saving and loading.</p>



<h2 class="wp-block-heading">Other Agentic Mode Notes</h2>



<p>You can toggle Agentic Mode on or off via IDE scripting with this command:</p>



<pre class="wp-block-code"><code>DoCommand("ToggleAgenticMode")</code></pre>



<p>Many coding agents have their own built-in browser and can use that to run and test Xojo web apps.</p>



<p>You can use Xojo while a coding agent is changing things, but keep in mind that changes you make might get overwritten by agent changes.</p>



<p>When Agentic Mode is turned on, Xojo adds an empty AGENTS.md file to the project folder that imports the XOJO-CODING.md guidelines file. You can add your own tips and suggestions to AGENTS.md (and even have the agent do it itself), but keep the link to XOJO-CODING.md intact. If you already have an AGENTs.md file in that folder that you added then Xojo won&#8217;t overwrite it, so be sure to tell it to reference XOJO-CODING.md with something like this:</p>



<pre class="wp-block-code"><code>&lt;xojo-coding&gt;
Before answering ANY message (including questions, suggestions, and planning) read the @XOJO-CODING.md file, right now.
Begin your first reply with one line: "XOJO-CODING.md loaded", then answer normally.
&lt;/xojo-coding&gt;</code></pre>



<p>The Agentic Mode setting is saved with your Xojo text project file. This allows you to have projects that automatically activate Agentic Mode when they are opened.</p>



<p>I hope you find Agentic Mode helpful for your workflow! Read more in the <a href="https://documentation.xojo.com/getting_started/using_the_ide/agentic_mode.html" target="_blank" rel="noreferrer noopener">Xojo Docs</a> or get started with the <a href="https://documentation.xojo.com/getting_started/quickstarts/ai_quickstart.html" target="_blank" rel="noreferrer noopener">AI QuickStart</a>.</p>



<figure class="wp-block-image size-full"><a href="https://knowyourmeme.com/memes/i-for-one-welcome-our-new-insect-overlords"><img loading="lazy" decoding="async" width="577" height="433" src="https://blog.xojo.com/wp-content/uploads/2026/09/image.png" alt="" class="wp-image-16568" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/image.png 577w, https://blog.xojo.com/wp-content/uploads/2026/09/image-300x225.png 300w" sizes="auto, (max-width: 577px) 100vw, 577px" /></a></figure>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Project and Project Item Reloading</title>
		<link>https://blog.xojo.com/2026/10/20/project-and-project-item-reloading/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:52:37 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[2026r3]]></category>
		<category><![CDATA[Version Control]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16447</guid>

					<description><![CDATA[Xojo 2026r3 brings some improvements to project and project item reloading, which make it easier to use Xojo with version control systems and AI coding&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2026r3 brings some improvements to project and project item reloading, which make it easier to use Xojo with version control systems and AI coding agents.</p>



<h2 class="wp-block-heading">Project Reloading</h2>



<p>In prior versions of Xojo you could reload a project, after it had been modified, by using File -&gt; Revert to Saved. This feature essentially closes and re-opens the entire project and it works with all project formats: Binary, XML and Text.</p>



<p>With 2026r3, this feature remains with a couple small tweaks. First, you can now reload the project without having to first modify it. An example when this might be useful is if you have just updated your Git client with the latest changes from your team and want to quickly reload the entire project.</p>



<p>This feature has also been renamed from &#8220;Revert to Saved&#8221; to &#8220;Reload Project&#8221;.</p>



<h2 class="wp-block-heading">Project Item Reloading</h2>



<p>Reloading the entire project can be handy, but is also somewhat overkill for text projects that save each project item as a separate file. If just a single file on disk was changed, then you may not want to reload the entire project, which could cause you to lose IDE changes, lose your place in the Navigator or just take too long.</p>



<p>You can now use File -&gt; Reload Item to reload the selected item in the Navigator. Note that &#8220;Item&#8221; in the menu is replaced with the name of the selected item. This feature reloads the selected item and keeps it selected.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>This feature is destructive</strong>, so if you have made changes to the project item in the IDE, they will be lost as the item is completely replaced by the version on the disk.</p>
</blockquote>



<p>It is a quick way to reload an item that has been changed by a version control update or an AI coding agent. Reloading is also a great way to fix a borked edit, rather than doing multiple Undos.</p>



<p>This feature only works with Text projects.</p>



<h2 class="wp-block-heading">Reload Changed Files</h2>



<p>Finally, you may have multiple files you want to reload but don&#8217;t know exactly which ones they are. This sort of thing can happen with a version control update or an AI coding agent. Rather than force you to reload the entire project, you can now use File -&gt; Reload Changed Files to reload the files on disk that are different than what is in the IDE.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>This feature is destructive</strong>, so if you have made changes to the project items in the IDE, they will be lost as the item is completely replaced by the version on the disk.</p>
</blockquote>



<p>This feature only works with Text projects.</p>



<h2 class="wp-block-heading">IDE Scripting</h2>



<p>The above features now also have equivalent IDE Scripting commands. They are:</p>



<ul class="wp-block-list">
<li>ReloadProject()</li>



<li>ReloadProjectItem(itemPath As String) As Boolean</li>



<li>ReloadChangedFiles()</li>
</ul>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Project Item Copy/Paste Improvements</title>
		<link>https://blog.xojo.com/2026/10/20/project-item-copy-paste-improvements/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:52:25 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[2026r3]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16536</guid>

					<description><![CDATA[Another improvement to Copy/Paste for code as text is that you can now paste a layout as text into your projects. This works for Window,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Another improvement to Copy/Paste for code as text is that you can now paste a layout as text into your projects. This works for Window, WebPage, MobileScreen and Container.</p>



<p>This is the output you get when copying a layout to text:</p>



<pre class="wp-block-code"><code>Window HelloThere
Inherits DesktopWindow
  Layout Property Width = 600
  Layout Property Height = 400
  Layout Property MinimumWidth = 64
  Layout Property MinimumHeight = 64
  Layout Property MaximumWidth = 32000
  Layout Property MaximumHeight = 32000
  Layout Property Title = "Hello World"
  Layout Property HasCloseButton = True
  Layout Property HasMaximizeButton = True
  Layout Property HasMinimizeButton = True
  Layout Property HasTitleBar = True
  Layout Property Resizeable = True
  Layout Property DefaultLocation = 2
  Layout Property Visible = True
  Layout Property ImplicitInstance = True
  Layout Property BackgroundColor = &amp;cFFFFFF
  Layout Property MenuBar = 1436252159

  Control Button1 Inherits DesktopButton
    Layout Property Scope = 2
    Layout Property Left = 20
    Layout Property Top = 55
    Layout Property Width = 171
    Layout Property Height = 20
    Layout Property LockLeft = True
    Layout Property LockTop = True
    Layout Property TabStop = True
    Layout Property AllowAutoDeactivate = True
    Layout Property Caption = "Hello"
    Layout Property Default = True
    Layout Property Enabled = True
    Layout Property Visible = True
    Layout Property FontName = "System"

    Private Sub Pressed() Handles Pressed
      MessageBox("Hello " + TextField1.Text)
    End Sub
  End Control

  Control TextField1 Inherits DesktopTextField
    Layout Property Scope = 2
    Layout Property Left = 20
    Layout Property Top = 11
    Layout Property Width = 171
    Layout Property Height = 38
    Layout Property LockLeft = True
    Layout Property LockTop = True
    Layout Property TabIndex = 1
    Layout Property TabStop = True
    Layout Property AllowAutoDeactivate = True
    Layout Property BackgroundColor = &amp;hFFFFFF
    Layout Property HasBorder = True
    Layout Property Enabled = True
    Layout Property TextColor = &amp;h000000
    Layout Property AllowFocusRing = True
    Layout Property Visible = True
    Layout Property FontName = "System"
    Layout Property Text = "Xojo"
  End Control

End Window</code></pre>



<p>You can copy that text and paste it back into a desktop project to add the window to it.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Note: Layouts that contain control sets do not copy/paste properly.</p>
</blockquote>



<p>But one other cool thing you can now do is paste the above window text into a different project type, such as a web project. The window gets converted to a WebPage and its controls are converted to web controls. Here is what the above window looks like when pasted into a web project:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="821" src="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.08.16@2x-1024x821.png" alt="" class="wp-image-16537" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.08.16@2x-1024x821.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.08.16@2x-300x240.png 300w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.08.16@2x-768x616.png 768w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.08.16@2x.png 1290w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>You could also paste it into an Android or iOS project:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="508" height="1024" src="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.09.12@2x-508x1024.png" alt="" class="wp-image-16538" srcset="https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.09.12@2x-508x1024.png 508w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.09.12@2x-149x300.png 149w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.09.12@2x-768x1547.png 768w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.09.12@2x-762x1536.png 762w, https://blog.xojo.com/wp-content/uploads/2026/09/CleanShot-2026-09-14-at-15.09.12@2x.png 822w" sizes="auto, (max-width: 508px) 100vw, 508px" /></figure>



<p>When you do this, your controls, code and properties are moved over, but the layout itself is not otherwise adjusted. Control sizes and positioning may need adjustments for the different size layouts. But this should provide a way to give you a quick jumpstart when migrating some UI between project types. If there is enough interest in this capability, perhaps we can add some conversion rules to help adjust control position and sizing between project types.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing DesktopTable: A More Capable DesktopListBox</title>
		<link>https://blog.xojo.com/2026/10/20/introducing-desktoptable-a-more-capable-desktoplistbox/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Tue, 20 Oct 2026 16:52:10 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[2026r3]]></category>
		<category><![CDATA[DesktopTable]]></category>
		<category><![CDATA[Listbox]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16615</guid>

					<description><![CDATA[DesktopTable is a new control introduced in Xojo 2026r3, it is designed as a drop-in replacement for DesktopListBox, while adding a range of features for&#8230;]]></description>
										<content:encoded><![CDATA[
<p>DesktopTable is a new control introduced in Xojo 2026r3, it is designed as a drop-in replacement for DesktopListBox, while adding a range of features for building richer, more capable tables.</p>



<p>Most existing DesktopListBox code will compile with little or no change when transitioning to DesktopTable. At the same time, DesktopTable adds features that previously required custom controls or additional code.</p>



<h2 class="wp-block-heading">What’s New?</h2>



<p>DesktopTable adds support for:</p>



<ul class="wp-block-list">
<li><strong>Frozen columns and rows</strong> — Keep important columns, headers, or totals visible while scrolling</li>
</ul>



<figure class="wp-block-video"><video height="1130" style="aspect-ratio: 1664 / 1130;" width="1664" controls src="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_FrozenColumns.mov"></video></figure>



<ul class="wp-block-list">
<li><strong>Merged cells</strong>&nbsp;— Span cells across rows and columns for titles, groupings, and custom layouts</li>



<li><strong>Sticky section headers</strong>&nbsp;— Keep section headers pinned as their section scrolls</li>



<li><strong>Hidden and reorderable columns</strong>&nbsp;— Hide columns without removing their data, or let users rearrange them</li>



<li><strong>Per-row heights</strong>&nbsp;— Set individual row heights and optionally allow users to resize rows</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="992" src="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_VariableRowHeights-1024x992.png" alt="" class="wp-image-16627" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_VariableRowHeights-1024x992.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_VariableRowHeights-300x291.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_VariableRowHeights-768x744.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_VariableRowHeights.png 1170w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list">
<li><strong>Insets</strong>&nbsp;— Add space before the first or after the last row</li>



<li><strong>Progress bars, checkboxes, and containers</strong>&nbsp;— Built-in cell types for richer data presentation</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="714" src="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.16.33-PM-1024x714.png" alt="" class="wp-image-16636" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.16.33-PM-1024x714.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.16.33-PM-300x209.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.16.33-PM-768x535.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.16.33-PM-1536x1071.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.16.33-PM.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="387" height="755" data-id="16646" src="https://blog.xojo.com/wp-content/uploads/2026/10/Win32ProgressBarCellType-2.png" alt="" class="wp-image-16646" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Win32ProgressBarCellType-2.png 387w, https://blog.xojo.com/wp-content/uploads/2026/10/Win32ProgressBarCellType-2-154x300.png 154w" sizes="auto, (max-width: 387px) 100vw, 387px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="387" height="785" data-id="16645" src="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIProgressBarCellType-1.png" alt="" class="wp-image-16645" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/WinUIProgressBarCellType-1.png 387w, https://blog.xojo.com/wp-content/uploads/2026/10/WinUIProgressBarCellType-1-148x300.png 148w" sizes="auto, (max-width: 387px) 100vw, 387px" /></figure>
</figure>



<ul class="wp-block-list">
<li><strong>Custom cell controls</strong>&nbsp;— Use&nbsp;<code>CellBoundsAt</code>&nbsp;to position your own controls over cells</li>



<li><strong>Automatic Right-to-Left support</strong>&nbsp;— The table automatically adapts and aligns columns and text for right-to-left languages</li>
</ul>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="777" data-id="16640" src="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.45.09-PM-1024x777.png" alt="" class="wp-image-16640" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.45.09-PM-1024x777.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.45.09-PM-300x228.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.45.09-PM-768x582.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.45.09-PM.png 1424w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="777" data-id="16639" src="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.44.23-PM-1024x777.png" alt="" class="wp-image-16639" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.44.23-PM-1024x777.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.44.23-PM-300x228.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.44.23-PM-768x582.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-1.44.23-PM.png 1424w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<ul class="wp-block-list">
<li><strong>Virtual data sources</strong>&nbsp;— Work with large datasets without storing every row in the control</li>



<li><strong>CSV and TSV support</strong>&nbsp;— Save and load table data directly</li>



<li><strong>Row swipe actions</strong>&nbsp;— Provide familiar leading and trailing actions on macOS, Windows, and Linux touchpads</li>
</ul>



<figure class="wp-block-video"><video height="1090" style="aspect-ratio: 1424 / 1090;" width="1424" controls src="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_MouseGesture.mov"></video></figure>



<ul class="wp-block-list">
<li><strong>Live column resizing</strong>&nbsp;— Respond while a column is being resized, as well as when resizing finishes</li>



<li><strong>Custom drawing and macOS vibrancy</strong>&nbsp;— More control over the table&#8217;s appearance and behavior</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="878" src="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_Translucent.png" alt="" class="wp-image-16623" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_Translucent.png 1000w, https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_Translucent-300x263.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_Translucent-768x674.png 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<h2 class="wp-block-heading">Moving from DesktopListBox</h2>



<p>The transition is intentionally straightforward. Change the super of your <code>DesktopListBox</code> control to&nbsp;<code>DesktopTable</code>, build your project, and address the few members that have been renamed.</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>DesktopListBox</th><th>DesktopTable</th></tr></thead><tbody><tr><td>HeaderAt</td><td>ColumnHeaderAt</td></tr><tr><td>HasHeader</td><td>HasColumnHeader</td></tr><tr><td>RefreshCell</td><td>RefreshCellAt</td></tr><tr><td>PressHeader</td><td>PressColumnHeaderAt</td></tr></tbody></table></figure>



<p>Most familiar APIs—including&nbsp;<code>AddRow</code>,&nbsp;<code>CellTextAt</code>,&nbsp;<code>ColumnCount</code>,&nbsp;<code>ColumnWidths</code>,&nbsp;<code>RemoveRowAt</code>, and&nbsp;<code>SelectedRowIndex</code>—retain their existing names.</p>



<h2 class="wp-block-heading">A Few Things to Check</h2>



<p>Some behavior is intentionally different. In particular, row reordering with a&nbsp;<code>DataSource</code>&nbsp;or expandable rows requires you to handle&nbsp;<code>DragReorderRows</code>, and row dragging requires&nbsp;<code>DragRow</code>&nbsp;to populate the&nbsp;<code>DragItem</code>&nbsp;and return&nbsp;<code>True</code>.</p>



<p>Sorting also removes merged cells, so applications using merged cells should re-apply their merges after sorting. Frozen rows retain their position and cannot be reordered.</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" />If you want to improve performance when adding and removing rows, you can set <code>AllowRowAnimation</code> to False.</p>



<h2 class="wp-block-heading">An Enhanced IDE Experience</h2>



<p>We couldn&#8217;t introduce DesktopTable without enhancing the IDE experience as well. Table editing in the IDE is now more intuitive, compared against DesktopListBox, making it easier to edit and work with your tables.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="750" data-id="16631" src="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.02.18-AM-1024x750.png" alt="" class="wp-image-16631" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.02.18-AM-1024x750.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.02.18-AM-300x220.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.02.18-AM-768x563.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.02.18-AM.png 1228w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">DesktopTable editor</figcaption></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="752" data-id="16632" src="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.03.53-AM-1024x752.png" alt="" class="wp-image-16632" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.03.53-AM-1024x752.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.03.53-AM-300x220.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.03.53-AM-768x564.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.03.53-AM.png 1220w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">DesktopListBox editor</figcaption></figure>
</figure>



<p>We&#8217;ve also updated the debugger to better handle DesktopTable contents, efficiently loading rows dynamically and allowing you to jump directly to and inspect specific rows without loading the entire table.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="500" src="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.14.48-AM-1024x500.png" alt="" class="wp-image-16633" srcset="https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.14.48-AM-1024x500.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.14.48-AM-300x147.png 300w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.14.48-AM-768x375.png 768w, https://blog.xojo.com/wp-content/uploads/2026/10/Screenshot-2026-10-06-at-11.14.48-AM.png 1134w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Final Thoughts</h2>



<p>DesktopTable gives existing DesktopListBox applications a familiar starting point while opening the door to considerably richer table interfaces. Stay tuned for more blog posts exploring many of its exciting new features!</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_FrozenColumns.mov" length="5935964" type="video/quicktime" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/10/DesktopTable_MouseGesture.mov" length="1111294" type="video/quicktime" />

			</item>
		<item>
		<title>Xcode 27 and iOS SDK 27: Debugging iOS Xojo apps</title>
		<link>https://blog.xojo.com/2026/09/15/xcode-27-and-ios-sdk-27-debugging-ios-xojo-apps/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 15 Sep 2026 19:31:56 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Xcode]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16544</guid>

					<description><![CDATA[From time to time Apple&#8217;s updates cause things that used to work to suddenly stop working. That is exactly what happens with the combination of&#8230;]]></description>
										<content:encoded><![CDATA[
<p>From time to time Apple&#8217;s updates cause things that used to work to suddenly stop working. That is exactly what happens with the combination of macOS Golden Gate, Xcode 27 and iOS SDK 27 (all release versions). With this setup, it is not possible to debug Xojo iOS projects on any of the iOS 27.0 Simulators, whether you are using the Simulator app or the new DeviceHub. Continue reading to find how to work around this.</p>



<span id="more-16544"></span>



<p>During internal testing for Xojo 2026r3, we identified this issue and have already fixed it. The workaround below is for users who have the previously described setup but are are running Xojo 2026r2.1 or earlier releases and need to test their iOS projects under any of the iOS 27 Simulators. Note that this issue doesn&#8217;t happen if you debug your iOS projects on a physical device running iOS 27.0.</p>



<h3 class="wp-block-heading">The workaround</h3>



<p>Until Xojo 2026r3 is released, the workaround is simple: just add a new Build Script to your iOS project, placed right before the Sign step, under the Build Settings &gt; iOS section of the Project Navigator:</p>



<p>Then add the following snippet of code to the associated Script Editor:</p>



<pre class="wp-block-code"><code>Var buildLocation As String = CurrentBuildLocation
Var appPackageName As String = CurrentBuildAppName

Var cleanBinaryName As String = ReplaceAll(appPackageName, ".app", "")

Var command As String
command = "cd " + buildLocation + _
" &amp;&amp; cd " + Chr(34) + appPackageName + Chr(34) + _
" &amp;&amp; install_name_tool -change /System/Library/PrivateFrameworks/WebKit.framework/WebKit /System/Library/Frameworks/WebKit.framework/WebKit " + Chr(34) + cleanBinaryName + Chr(34) + _
" &amp;&amp; cd .. " + _
" &amp;&amp; xattr -cr " + Chr(34) + appPackageName + Chr(34) + _
" &amp;&amp; codesign --force --deep --sign - " + Chr(34) + appPackageName + Chr(34)

Var result As String = DoShellCommand(command)</code></pre>



<p>To test it, select Project &gt; Run On and choose any of the available iOS 27.0 Simulators already installed on your Mac as part of the Xcode plus iOS SDK 27 installation process.</p>



<p>If everything goes well, your iOS project will run without issues as it did with previous Xcode and iOS SDK configurations, or even during the beta cycle for Xcode 27.0 and iOS SDK 27.0.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Postmortem: Developer ID Selector for macOS Apps</title>
		<link>https://blog.xojo.com/2026/09/10/postmortem-developer-id-selector-for-macos-apps/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 10 Sep 2026 10:47:00 +0000</pubDate>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Apple Developer Account]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16515</guid>

					<description><![CDATA[Some time ago, an edge case involving macOS development certificates came up on the Xojo Forum. Despite the improvements introduced in Xojo 2026r1, I have&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Some time ago, an edge case involving macOS development certificates came up on the <a href="https://forum.xojo.com/t/developer-id-popup-invalid-entry/88762">Xojo Forum</a>. Despite the improvements introduced in Xojo 2026r1, I have to admit that this particular scenario fell outside of what we accounted for. Continue reading to learn more about this issue and its solution.</p>



<span id="more-16515"></span>



<p>The issue the user was dealing with was the Developer ID popup menu showing a different name than expected for the Developer ID Team. Interestingly, this problem didn&#8217;t occur on his second Mac.</p>



<p>As a result, he was not able to select any of the &#8220;Build For&#8221; options, because the remaining developer certificates installed on that Mac were issued under the same Team ID but with a different Company Name.</p>



<p>In this particular case, a couple of X.509 certificates OIDs (think of these as certificate attributes) are worth highlighting:</p>



<ul class="wp-block-list">
<li><strong>2.5.4.11 &#8211; Organizational Unit Name</strong> <strong>(OU)</strong>: This corresponds to the Team ID for Apple Developer Certificates. It is unique and never changes.</li>



<li><strong>2.5.4.10 &#8211; Organization Name (O)</strong>, also known as the Legal Entity or Company Name: This value can be changed from the Apple Developer portal, under Account &gt; Membership Details, but only if your developer program membership is registered as an Organization (not an Individual).</li>
</ul>



<h3 class="wp-block-heading">The underlying problem</h3>



<p>In this particular case, several factors converged:</p>



<ul class="wp-block-list">
<li>The certificate issued under the unexpected Team name had expired long time ago but was still present on that Mac. This part wasn&#8217;t too bad, Xojo can safely ignore expired certificates.</li>



<li>The real issue was that this expired certificate had been installed on that Mac long before the other (correct) certificates using the current Organization Name. Because of this, when Xojo iterated through the installed certificates at the system level, it encountered the expired one <em>first</em> &#8211; and mistakenly used its Organization Name for all certificates sharing the same Team ID. </li>
</ul>



<p>Now that we&#8217;re aware of this behavior, we have fixed it for Xojo 2026r3.</p>



<h3 class="wp-block-heading">The Solution</h3>



<p>Once we identified what was happening, the fix to this particular case was simple: delete the expired, offending certificate from the Keychain Access app on that Mac.</p>



<h3 class="wp-block-heading">The Recipe</h3>



<p>If you run into a similar issue, whether it is trouble selecting a specific Team ID, or missing &#8220;Build For&#8221; options, the best first step is to use the Inspect&#8230; option under the Developer ID popup menu.</p>



<p>The Certificate Inspector lists all installed certificates for every Team in a much simpler way than digging through Keychain Access. It also provides additional details and, when possible, direct actions to resolve some of the most common issues related to managing your Apple Developer Certificates.</p>



<h3 class="wp-block-heading">Reviewing Certificates in More Depth</h3>



<p>Alternatively, or if you are running a Xojo version prior to Xojo 2026r1, you can inspect your certificates manually by running the following command in Terminal:</p>



<pre class="wp-block-code"><code>security find-certificate -a -p | awk '/---BEGIN CERTIFICATE---/{flag=1; print; next} /---END CERTIFICATE---/{print; flag=0; print "---END---"} flag' | while IFS= read -r line; do if &#91; "$line" = "---END---" ]; then echo "$cert" | openssl x509 -noout -subject -enddate 2&gt;/dev/null; cert=""; else cert="$cert$line"$'\n'; fi; done</code></pre>



<p>The output will list, in the Terminal window, all the Apple Developer certificates found on your computer along with some key pieces of information worth inspecting:</p>



<ul class="wp-block-list">
<li><strong>CN (Common Name</strong>): Indicates the certificate type, for example, Development, Developer ID Application, or any other Apple development certificate.</li>



<li><strong>OU (Organizational Unit/Team ID):</strong> Remember, this value never changes for your Apple Developer Program membership.</li>



<li><strong>O (Organization</strong>): The current Organization Name associated with the certificate. This can be changed, but only for Organization-type membership (not Individual).</li>



<li><strong>notAfter</strong>. The expiration date for that certificate.</li>
</ul>



<h3 class="wp-block-heading">Conclusion</h3>



<p>This edge case is a good reminder that expired certificates sitting in your Keychain can quietly cause unexpected issues. Thanks to the fix in Xojo 2026r3 and the new Certificate Inspector, spotting and resolving these problems are now much easier.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Spotlight On: Christian Wheel</title>
		<link>https://blog.xojo.com/2026/09/02/spotlight-on-christian-wheel/</link>
		
		<dc:creator><![CDATA[Alyssa Foley]]></dc:creator>
		<pubDate>Wed, 02 Sep 2026 08:00:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Spotlight On]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16434</guid>

					<description><![CDATA[Spotlight On posts focus on Xojo community members. We’ll use this space to tell the stories of people using Xojo, share amazing Xojo-made apps and&#8230;]]></description>
										<content:encoded><![CDATA[
<p><em>Spotlight On posts focus on Xojo community members. We’ll use this space to tell the stories of people using Xojo, share amazing Xojo-made apps and spread awareness of community resources. If you have an app, a project or a person you want to see featured in Spotlight On,&nbsp;<a href="mailto:hello@xojo.com" target="_blank" rel="noreferrer noopener">tell us about it</a>!</em></p>



<p id="block-55976937-312d-4290-a3af-8fb3efb0bc5a">You may have seen this thread in the Forums, <a href="https://forum.xojo.com/t/this-is-the-farthest-ive-pushed-canvases/88540?u=alyssa_foley" target="_blank" rel="noreferrer noopener">This is the farthest I&#8217;ve pushed canvases</a>, showcasing Xojo user Christian Wheel&#8217;s use of the Canvas control from a custom animated GIF renderer built entirely in Xojo code, to slick audio production tools for radio and podcasting. Many people reached out and wanted to know more about this project and what else Christian has been doing with Xojo. As it turns out, he&#8217;s been doing quite a lot! In this post Christian talks about vibe coding, laser cutters and why Xojo&#8217;s &#8220;idea-to-executable&#8221; speed made it the perfect tool for getting things done, at Apple and beyond.</p>



<h3 class="wp-block-heading" id="block-a4613329-ca21-4353-8768-42b1cbea83b8"><strong>Mac, Windows or Linux?</strong></h3>



<p id="block-fb648297-1c52-4f1d-8c2f-2462959afd83">Windows &amp; MacOS, I use both daily. I generally prefer Windows desktops and Mac laptops, even though I do have a Mac Studio and a Windows laptop too. I literally have dozens of computers, haha.</p>



<h3 class="wp-block-heading" id="block-474020f5-55c7-413b-9ac6-6c20451a9978"><strong>What do you wish more people would ask you about when it comes to your work? Is there an aspect of your work that people often overlook but you wish they were more curious about?</strong></h3>



<p id="block-35c0050a-d613-41b6-be0c-e2b2fdc801ab">Honestly, nobody really asks me about my work! Most people know me from my work as a radio host and DJ, so that&#8217;s where the majority of my interactions occur with other people. My software development endeavors have always been my &#8220;side-gig&#8221; even though I&#8217;ve had some successes in that area too. Just the fact that I get to talk about computers with anybody is a breath of fresh air for me.</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="800" height="1016" src="https://blog.xojo.com/wp-content/uploads/2026/08/01-Christian-What-do-you-wish-more-people-would-ask-you-about.jpg" alt="" class="wp-image-16473" style="aspect-ratio:0.7874136843886009;width:635px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/01-Christian-What-do-you-wish-more-people-would-ask-you-about.jpg 800w, https://blog.xojo.com/wp-content/uploads/2026/08/01-Christian-What-do-you-wish-more-people-would-ask-you-about-236x300.jpg 236w, https://blog.xojo.com/wp-content/uploads/2026/08/01-Christian-What-do-you-wish-more-people-would-ask-you-about-768x975.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /></figure>



<h3 class="wp-block-heading" id="block-14203cf8-a34d-447f-92fb-8083c6904bae"><strong>What software or skill is on your &#8220;Learn Next&#8221; list and why?</strong></h3>



<p id="block-5c38c051-d484-4063-85dc-f205a43c6f54">Last year I picked up a laser cutter and 3D printer and haven’t yet been able to explore them as much as I would like to. I’ve done some 3D modeling for use in animations and visuals, but that’s very, very different from modeling tangible objects, where there needs to be a lot more consideration for engineering principles involved. I also feel like it’s cliche in 2026 to add “AI” to a list of things to learn, but it’s genuinely true. I’ve been running some local models and while I’ve dabbled a bit, I’d like to dive more into training my own models, <a href="https://en.wikipedia.org/wiki/LoRA_(machine_learning)" target="_blank" rel="noreferrer noopener">LoRAs</a>, etc.</p>



<p>Between those maker tools and my UV Printer, I want to lean more into making aesthetic mods for PC hardware and getting more into exotic and custom PC builds.</p>



<p id="block-5c38c051-d484-4063-85dc-f205a43c6f54">Even though I&#8217;ve been a &#8220;content creator&#8221; on the radio for decades (including a &#8220;call for help&#8221; radio show about tech, software and hardware), I plan on going all-in on YouTube in the tech space shortly, covering everything from PC part reviews, unboxings, benchmarks, build guides, troubleshooting, homelab projects, creator gear, software tools, Apple, and extreme-themed PC builds. I&#8217;ve made significant investments in building studio spaces and an 8K cinema-grade production pipeline, so I&#8217;m taking this seriously!</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="768" height="1024" src="https://blog.xojo.com/wp-content/uploads/2026/08/02-Laser-Cutter-What-software-or-skill-is-on-your-Learn-Next-list-768x1024.jpg" alt="" class="wp-image-16474" style="aspect-ratio:0.7499961852445258;width:582px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/02-Laser-Cutter-What-software-or-skill-is-on-your-Learn-Next-list-768x1024.jpg 768w, https://blog.xojo.com/wp-content/uploads/2026/08/02-Laser-Cutter-What-software-or-skill-is-on-your-Learn-Next-list-225x300.jpg 225w, https://blog.xojo.com/wp-content/uploads/2026/08/02-Laser-Cutter-What-software-or-skill-is-on-your-Learn-Next-list-1152x1536.jpg 1152w, https://blog.xojo.com/wp-content/uploads/2026/08/02-Laser-Cutter-What-software-or-skill-is-on-your-Learn-Next-list.jpg 1322w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure>



<h3 class="wp-block-heading">What is something that has surprised you about coding in the last 5 years?</h3>



<p>I definitely did not have the rise of Vibe Coding on my Bingo card. There are so many interesting aspects to it. At the end of the day, getting more people interested in software development is a great thing for the industry. There are lots of people in our field who enjoy gatekeeping it, and I understand that the industry was already fiercely competitive before the flood gates opened to everyone. But this is the new reality and everyone has to adapt. But on the the other hand, for people without a strong background in development, experience with security and proper testing, you end up with a lot of buggy, potentially dangerous applications created by those without the experience to put in the final 10% of every project (which, as we know, is what takes 90% of the time). This is all evolving so fast and there&#8217;s no doubt in my mind that we&#8217;re going to see some very high-profile embarrassments and systemic software failures caused by vibe coding. And in a way, we have to, that&#8217;s the only way things will improve.</p>



<h3 class="wp-block-heading">Xojo isn&#8217;t the only tool in your kit. What is another piece of software more people should know about?</h3>



<p>There are so many great third-party tools in the Xojo ecosystem. While I love learning new things, sometimes you just need to get something done and it&#8217;s faster to buy something rather than build it yourself. Shout outs, in no particular order, to Christian Schmitz/MBS, Anthony Cyphers/GraffitiSuite, Tim Parnell/Lifeboat+TPLM, Jim McKay/PiDog, Björn Eiriksson/Einhugur, Marc Zeedar/xDev, and so many more that really boost the Xojo experience. For testing, Parallels on Mac, and VMware Workstation on Windows, are invaluable to me. The ability to take and revert to snapshots in seconds is like magic. You also can never underestimate a good text or hex editor. For text on macOS I use BBEdit and on Windows Notepad3. UltraEdit is fantastic for hex on both.</p>



<h3 class="wp-block-heading">How/When did you find Xojo? What did you first build with Xojo?</h3>



<p>I discovered REALbasic in the early 2000&#8217;s when Microsoft made the decision to go all-in on VB.Net and away from VB6/COM. While it shared a lot of the same keywords and syntax, VB.Net is a fundamentally different language. So I figured if I had to learn a new-but-similar language anyway, I might as well learn something cross-platform. For much of the decade I was a DIY Windows snob though, and refused to spend on Apple hardware, which kept me using OS X on Virtual Machines and such. Once the iPhone became popular I finally gave in and bought an iPhone to complement my Android, and a MacBook Pro to complement my gaming laptop. Most of the things I built with Xojo were just internal tools, things that improved my own workflow in radio and DJing. Many of my tools proved useful to coworkers, and with the increase in Apple&#8217;s hardware market share, Xojo was instrumental in allowing me to create distributables for everyone.</p>



<h3 class="wp-block-heading">What do you build with Xojo now?</h3>



<p>Most of the things I’m building at the moment are audio related. I have a ton of legacy VB code that deals with audio on Windows, and I’m slowly Xojo-ing it to be cross-platform. One of my main apps I’ve been developing for 4 years now, is called PlaylistPal. It’s a playlisting app for DJ’s that basically lets them import playlists from any source, streaming service, or even a text request list, and load it into their DJ software. There’s a lot of work done under-the-hood to resolve songs into universal ID’s and let DJs match those playlist entries with music they already own.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="384" src="https://blog.xojo.com/wp-content/uploads/2026/08/04-PlaylistPal-What-do-you-build-with-Xojo-now-1024x384.png" alt="" class="wp-image-16476" style="width:664px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/04-PlaylistPal-What-do-you-build-with-Xojo-now-1024x384.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/08/04-PlaylistPal-What-do-you-build-with-Xojo-now-300x113.png 300w, https://blog.xojo.com/wp-content/uploads/2026/08/04-PlaylistPal-What-do-you-build-with-Xojo-now-768x288.png 768w, https://blog.xojo.com/wp-content/uploads/2026/08/04-PlaylistPal-What-do-you-build-with-Xojo-now-1536x576.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/08/04-PlaylistPal-What-do-you-build-with-Xojo-now-2048x768.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I’ve also been building audio production software for radio shows and podcasts. As shown in the forum post, the Xojo canvas is a powerful tool. It actually reminds me of the old days of DOS programming when you had to draw everything yourself, handle mouse and keyboard input at a very low-level, and actually optimize your code to run fast.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="660" src="https://blog.xojo.com/wp-content/uploads/2026/08/05-Segue-Editor-What-do-you-build-with-Xojo-now-1024x660.png" alt="" class="wp-image-16478" style="aspect-ratio:1.5515459820364041;width:658px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/05-Segue-Editor-What-do-you-build-with-Xojo-now-1024x660.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/08/05-Segue-Editor-What-do-you-build-with-Xojo-now-300x193.png 300w, https://blog.xojo.com/wp-content/uploads/2026/08/05-Segue-Editor-What-do-you-build-with-Xojo-now-768x495.png 768w, https://blog.xojo.com/wp-content/uploads/2026/08/05-Segue-Editor-What-do-you-build-with-Xojo-now-1536x989.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/08/05-Segue-Editor-What-do-you-build-with-Xojo-now-2048x1319.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>It has been fun to create new UI elements in the canvas. Another Canvas-related project I’ve been working on is an animated GIF control, completely in Xojo code. It parses the binary image data of an animated GIF file and uses a timer for each frame’s duration. It can be a bit slow to load all the frames to memory, but it does so in a thread so as to not slow your app down. It supports transparency via alpha channel or color replacement. It’s containerized so you just drop it into a Window, set some properties, call some methods, and receive events. I still have some bugs to work out but it’s been a lot of fun to develop.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-4 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="754" data-id="16479" src="https://blog.xojo.com/wp-content/uploads/2026/08/06-Segment-Editor-What-Do-You-Build-With-Xojo-Now-1024x754.png" alt="" class="wp-image-16479" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/06-Segment-Editor-What-Do-You-Build-With-Xojo-Now-1024x754.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/08/06-Segment-Editor-What-Do-You-Build-With-Xojo-Now-300x221.png 300w, https://blog.xojo.com/wp-content/uploads/2026/08/06-Segment-Editor-What-Do-You-Build-With-Xojo-Now-768x566.png 768w, https://blog.xojo.com/wp-content/uploads/2026/08/06-Segment-Editor-What-Do-You-Build-With-Xojo-Now-1536x1132.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/08/06-Segment-Editor-What-Do-You-Build-With-Xojo-Now.png 1800w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="799" data-id="16480" src="https://blog.xojo.com/wp-content/uploads/2026/08/07-Animated-GIF-Canvas-What-Do-You-Build-With-Xojo-Now-1024x799.png" alt="" class="wp-image-16480" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/07-Animated-GIF-Canvas-What-Do-You-Build-With-Xojo-Now-1024x799.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/08/07-Animated-GIF-Canvas-What-Do-You-Build-With-Xojo-Now-300x234.png 300w, https://blog.xojo.com/wp-content/uploads/2026/08/07-Animated-GIF-Canvas-What-Do-You-Build-With-Xojo-Now-768x600.png 768w, https://blog.xojo.com/wp-content/uploads/2026/08/07-Animated-GIF-Canvas-What-Do-You-Build-With-Xojo-Now-1536x1199.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/08/07-Animated-GIF-Canvas-What-Do-You-Build-With-Xojo-Now.png 1564w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p>I also just recently fell into a project creating digital signage software, for billboards, restaurant menu boards, trade show screens and such. I needed software to control my own LCD panels and found the existing options lacking or overly complicated, so I decided to create my own in Xojo. The wonderful thing that Xojo brings to a project like this is I can compile for everything! The user can create their slideshow on Windows or Mac and run the project connected to their screens on anything from a Raspberry Pi to a Mac Mini.</p>



<h3 class="wp-block-heading">Do you earn a living with Xojo?</h3>



<p>At the moment, no. I don&#8217;t have anything for sale. But eventually, once my software is at a point where I feel it&#8217;s marketable I&#8217;ll flip that switch. Until then, it&#8217;s test, test, test!</p>



<h3 class="wp-block-heading">Do you use Xojo for any hobbies?</h3>



<p>I find that Xojo, both Desktop and Web, makes GREAT frontends for AI applications. I have a great little AI stack for audio that I&#8217;ve developed on Windows. On Desktop I can build a UI to run the python scripts directly and capture their output, or I can build it into a Web App and create an API that I call from a macOS or Web app. The same python scripts can be Dockerized for Linux deployment when I want to put them on the internet and build a real web app to control them. I recently started playing with RunPod, which lets me load my Docker apps in their cloud and spins up instances on demand, so they can use cloud GPUs that aren&#8217;t practical to host locally.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="916" src="https://blog.xojo.com/wp-content/uploads/2026/08/08-ExpressiveTTS-Do-you-use-Xojo-for-any-hobbies-1024x916.png" alt="" class="wp-image-16481" style="aspect-ratio:1.1179199358570528;width:710px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/08-ExpressiveTTS-Do-you-use-Xojo-for-any-hobbies-1024x916.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/08/08-ExpressiveTTS-Do-you-use-Xojo-for-any-hobbies-300x269.png 300w, https://blog.xojo.com/wp-content/uploads/2026/08/08-ExpressiveTTS-Do-you-use-Xojo-for-any-hobbies-768x687.png 768w, https://blog.xojo.com/wp-content/uploads/2026/08/08-ExpressiveTTS-Do-you-use-Xojo-for-any-hobbies-1536x1375.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/08/08-ExpressiveTTS-Do-you-use-Xojo-for-any-hobbies.png 1924w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">What&#8217;s your biggest Xojo success?</h3>



<div class="wp-block-media-text is-stacked-on-mobile" style="grid-template-columns:25% auto"><figure class="wp-block-media-text__media"><img loading="lazy" decoding="async" width="768" height="1024" src="https://blog.xojo.com/wp-content/uploads/2026/08/09-Apple-Whats-your-biggest-Xojo-success-768x1024.jpg" alt="" class="wp-image-16482 size-full" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/09-Apple-Whats-your-biggest-Xojo-success-768x1024.jpg 768w, https://blog.xojo.com/wp-content/uploads/2026/08/09-Apple-Whats-your-biggest-Xojo-success-225x300.jpg 225w, https://blog.xojo.com/wp-content/uploads/2026/08/09-Apple-Whats-your-biggest-Xojo-success-1152x1536.jpg 1152w, https://blog.xojo.com/wp-content/uploads/2026/08/09-Apple-Whats-your-biggest-Xojo-success.jpg 1322w" sizes="auto, (max-width: 768px) 100vw, 768px" /></figure><div class="wp-block-media-text__content">
<p>Probably using it at Apple. I worked for Apple for a few years and quickly identified the need for a few internal tools to make things simpler for our department. I used Xojo to create them and it was fast and easy to work with, simple to make updates, and it was just accepted. Nobody questioned what language I was using, they just cared about functionality. But Xojo&#8217;s rapid idea-to-executable workflow really worked in my favor at Apple.</p>
</div></div>



<h3 class="wp-block-heading">Looking back, how long did it take for your app vision to evolve from a blank project into a working solution?</h3>



<p>What I like about Xojo is that you can go from nothing to something SO quickly. It&#8217;s adding all the niceties that can take a long time. Little touches and details can all be accomplished if you&#8217;re willing to put in the work. Of course, not every project requires you to put in the work. You don&#8217;t need smooth animations and lots of options for everything you build. I think for most of us, we have an idea, spend some time in the code editor building out our algorithm, and then haphazardly toss a few buttons and textfields onto a Window to test things out. Only once we&#8217;ve got something somewhat-working do we refine the user experience and engage with the artistic side of the app. That means for personal tools, you can go from zero to finished in a few minutes or hours. But for a major project… I mean gosh, I&#8217;ve been building PlaylistPal for FOUR YEARS and still make updates constantly, but I had friends testing it by the end of the first week. Your app is really as good as the time you put into it, but the benefit of Xojo is that you&#8217;re generally free to pause and release at any point along the way.</p>



<h3 class="wp-block-heading">How do you decide when to use Xojo versus another tool or language?</h3>



<p>I think personally, these days I default to Xojo unless the project has a need that Xojo can&#8217;t address. For example, I recently had a Windows project that required a single portable executable with no accompanying libraries. I could, of course, use Xojo and wrap up the project in something like BoxedApp, but that can end up being problematic in other ways. So I ended up using .Net for that one. But other than exceptions like that, Xojo is my go-to these days. I have decades of classes and modules that already have a bunch of code that I&#8217;m used to including in every project, so I try to stick to it as much as possible unless there&#8217;s a reason to use something else.</p>



<h3 class="wp-block-heading">What does Xojo do particularly well compared to other tools?</h3>



<p>The basics between platforms is largely the same and the differences are insulated from you, for the most part. Obviously the more things you want to do that deviate from standard behaviors, the more work you&#8217;ll need to put in, but once you wrap your head around the way Xojo does things, there&#8217;s only a little bit you need to learn about other platforms in order to implement your vision.</p>



<h3 class="wp-block-heading">Which three Xojo language features or framework capabilities do you find yourself relying/using on the most?</h3>



<ul class="wp-block-list">
<li>Ease of cross-platform. Most things just work seamlessly across platforms and I don&#8217;t have to worry about it. Really intricate algorithms that I wrote for desktop can be literally copied and pasted into a web app. That&#8217;s just so… <em>chef&#8217;s kiss</em>.</li>



<li>Canvases. They&#8217;re a blank slate that lets you create whatever you can imagine. If you want a button with a dragon on it that breathes fire when you click it, as long as you&#8217;ve got the time and the talent, you can create it. </li>



<li>I&#8217;ve been diving deep into Xojo Web lately. I love that you can do anything from build a full web app with pages and controls or go really low-level to respond to individual HTTP requests. It&#8217;s really great.</li>
</ul>



<h3 class="wp-block-heading">How important has the Xojo community been in your development journey?</h3>



<p>Absolutely vital. The community is a lifeline, everyone there truly wants to be helpful to others. You also never know when someone on the Xojo dev team may drop in to offer some advice too. I know this for sure, I would have never been able to create the things I have without the community.</p>



<h3 class="wp-block-heading">Where do you typically go when you get stuck?</h3>



<p>Depends on what I get stuck on! If it&#8217;s a language or framework question, it&#8217;s either the Xojo Documentation site, or Google to end up on a Xojo forum post. If it&#8217;s an approach or algorithm question, StackOverflow has a lot of answers. Chatbots are also getting quite adept at answering some of these question as well.</p>



<h3 class="wp-block-heading">If you were introducing Xojo to a friend, which three words would you use to describe it?</h3>



<p>I really only need one word: Versatile. I really believe that versatility is Xojo&#8217;s greatest strength.</p>



<h3 class="wp-block-heading">What features or improvements would you most like to see in future Xojo releases?</h3>



<p>Something I think Xojo could do better is to build in a lot of the controls or behaviors that we end up creating ourselves. Some control examples from .Net that ship with the framework include CheckedListBox, FileSystemWatcher, ListView, LinkLabel, PropertyGrid, SplitContainer, StatusStrip, TreeView, etc. These are all things that we could (and many of us have) build ourselves but it would be nice to have a larger collection of controls built in.</p>



<h3 class="wp-block-heading">What advice would you give to someone just getting started with Xojo?</h3>



<ul class="wp-block-list">
<li>Make sure you&#8217;ve got an open mind! The &#8220;Xojo way&#8221; of doing things is not always the same as the way you may be used to. </li>



<li>Don&#8217;t use DoEvents! The temptation is huge, and I know it worked in VB, but there&#8217;s a good reason why everyone advises against it. There are a select few times when it&#8217;s appropriate and when you encounter one you will likely have enough experience with the language by then to know it&#8217;s okay. Until then, just say no!</li>



<li>Have patience with folks in the forums. Everyone really does want to help, even when things get heated. There&#8217;s a wide mix of people with varying experience levels, spoken languages, neurotypical/neurodivergent, and varying stress levels, so keep in mind that everyone generally means well even if they may have a hard time expressing it at times.</li>
</ul>



<p><em>Thank you to Christian Wheel for answering questions and sharing his Xojo experience with the community.&nbsp;If you have an app, a project or a person you want to see featured in Spotlight On,&nbsp;<a href="mailto:hello@xojo.com" target="_blank" rel="noreferrer noopener">tell us about it</a>!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Protect Passwords, Tokens, Requests, and Updates with the Crypto Module</title>
		<link>https://blog.xojo.com/2026/09/01/protect-passwords-tokens-requests-and-updates-with-the-crypto-module/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Tue, 01 Sep 2026 22:04:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AES]]></category>
		<category><![CDATA[application security]]></category>
		<category><![CDATA[Crypto]]></category>
		<category><![CDATA[Ed25519]]></category>
		<category><![CDATA[Encryption]]></category>
		<category><![CDATA[Hashing]]></category>
		<category><![CDATA[HMAC]]></category>
		<category><![CDATA[PBKDF2]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16507</guid>

					<description><![CDATA[The&#160;Crypto&#160;module covers several different jobs. The hard part is usually not finding a function; it is choosing the right one for the problem in front&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The&nbsp;<a href="https://documentation.xojo.com/api/cryptography/crypto.html" target="_blank" rel="noreferrer noopener"><code>Crypto</code></a>&nbsp;module covers several different jobs. The hard part is usually not finding a function; it is choosing the right one for the problem in front of you.</p>



<p>Which function should you use when your app needs to:</p>



<ul class="wp-block-list">
<li>remember a user&#8217;s password,</li>



<li>save an API token in a local settings file,</li>



<li>check that an API request was not changed, or</li>



<li>verify that an update came from you?</li>
</ul>



<pre class="wp-block-preformatted">The examples below answer those questions with small, focused scenarios. They show where each function fits. They are not complete security products.</pre>



<p>A good starting point is:</p>



<ul class="wp-block-list">
<li>Use&nbsp;<a href="https://documentation.xojo.com/api/cryptography/crypto.html#crypto-pbkdf2" target="_blank" rel="noreferrer noopener"><strong>PBKDF2</strong></a>&nbsp;when you need to check a password later.</li>



<li>Use&nbsp;<a href="https://documentation.xojo.com/api/cryptography/crypto.html#crypto-aesencrypt" target="_blank" rel="noreferrer noopener"><strong>AES</strong></a>&nbsp;when you need to hide data that your app must read again.</li>



<li>Use&nbsp;<a href="https://documentation.xojo.com/api/cryptography/crypto.html#crypto-hmac" target="_blank" rel="noreferrer noopener"><strong>HMAC</strong></a>&nbsp;when two trusted systems share a secret and need to detect changed messages.</li>



<li>Use&nbsp;<a href="https://documentation.xojo.com/api/cryptography/crypto.html#crypto-ed25519generatekeypair" target="_blank" rel="noreferrer noopener"><strong>Ed25519</strong></a>&nbsp;when one side signs data and other parties only need to verify it.</li>
</ul>



<h2 class="wp-block-heading" id="example-1-remembering-a-users-password-with-pbkdf2">Example 1: Remembering a user&#8217;s password with PBKDF2</h2>



<p>Imagine a desktop or web app with a login screen. When a user creates an account, you need to save something that lets you check the password later.</p>



<pre class="wp-block-preformatted">Do not save this:&nbsp;correct horse battery staple</pre>



<p>If somebody gets the database, they immediately have the user&#8217;s password. A plain SHA-256 hash is not a good replacement because attackers can calculate fast hashes very quickly and try large lists of common passwords. PBKDF2 is designed for this job. It combines the password with a random salt and repeats the calculation many times.</p>



<pre class="wp-block-code"><code>Var password As String = "correct horse battery staple"
Var salt As String = EncodeHex(Crypto.GenerateRandomBytes(16))
Var iterations As Integer = 100000
Var derived As MemoryBlock = Crypto.PBKDF2(salt, password, iterations, 32, Crypto.HashAlgorithms.SHA2_512)
Var storedHash As String = EncodeHex(derived)</code></pre>



<p>Save&nbsp;<code>salt</code>,&nbsp;<code>iterations</code>, the algorithm name, and&nbsp;<code>storedHash</code>&nbsp;in the user&#8217;s record. The salt does not need to be secret. You need it again when the user logs in.</p>



<pre class="wp-block-code"><code>Var suppliedPassword As String = "correct horse battery staple"
Var calculated As MemoryBlock = Crypto.PBKDF2(salt, suppliedPassword, iterations, 32, Crypto.HashAlgorithms.SHA2_512)
Var calculatedHash As String = EncodeHex(calculated)

If calculatedHash = storedHash Then
  MessageBox("Password accepted")
Else
  MessageBox("Password rejected")
End If</code></pre>



<p>The app never needs to recover the original password. It calculates the value again and compares it with the stored one.</p>



<p>The iteration count in this example is only an example. Test it on the slowest computer you support. Store the count with the hash so you can increase it later and update old records after a successful login.</p>



<p>Use&nbsp;<code>Crypto.GenerateRandomBytes</code>&nbsp;here because the salt must not be predictable. The same function is useful when you need a random token, nonce, or initialization vector.</p>



<h2 class="wp-block-heading" id="example-2-saving-an-api-token-in-an-encrypted-settings-file">Example 2: Saving an API token in an encrypted settings file</h2>



<p>Now imagine a desktop app that lets a user connect to an online service. After the user enters an API token, the app should remember it without saving readable text to its settings file.</p>



<p>This is a job for symmetric encryption. The app uses the same secret key to encrypt and decrypt the value.</p>



<p>AES accepts keys that are 16, 24, or 32 bytes long. The initialization vector is 16 bytes for AES. This example uses a 32-byte key and a new 16-byte IV:</p>



<pre class="wp-block-code"><code>Var secretKey As String = Crypto.GenerateRandomBytes(32)
Var initializationVector As MemoryBlock = Crypto.GenerateRandomBytes(16)
Var apiToken As String = "token-from-the-service"
Var encryptedToken As MemoryBlock = Crypto.AESEncrypt(secretKey, apiToken, Crypto.BlockModes.CBC, initializationVector)</code></pre>



<p>To read the token later:</p>



<pre class="wp-block-code"><code>Var decryptedToken As MemoryBlock = Crypto.AESDecrypt(secretKey, encryptedToken, Crypto.BlockModes.CBC, initializationVector)
Var apiTokenAgain As String = decryptedToken</code></pre>



<p>The IV is not a password and does not need to be secret. Save it with the encrypted value. You need the same IV for decryption.</p>



<p>The key is the difficult part. If you generate a new key every time the app starts, the app cannot decrypt yesterday&#8217;s settings. A real application must store the key in a suitable secret store, derive it from a user-provided secret, or keep the sensitive value on a server. Do not put a production key directly in the source code.</p>



<p>The encrypted record might contain these fields:</p>



<pre class="wp-block-code"><code>version
iv
ciphertext</code></pre>



<p>Store the IV and ciphertext as Base64 or hexadecimal text if the settings format cannot hold binary data. Store a version so you can change the format later.</p>



<p>CBC encryption hides the token, but it does not prove that the ciphertext was not changed. For real data, authenticate the encrypted record as well. With CBC, that means using an encrypt-then-MAC design with a separate MAC key. Another option is a vetted authenticated-encryption library or a service that provides an AEAD mode.</p>



<p>Do not reuse an IV with the same key, and do not use ECB mode for application data.</p>



<h2 class="wp-block-heading" id="example-3-signing-an-api-request-with-hmac">Example 3: Signing an API request with HMAC</h2>



<p>Suppose you control both a client and a server application. The client sends an order to the server, and the server needs to know whether somebody changed the request while it was being sent.</p>



<p>The client and server can share a secret. The client signs the request with HMAC, and the server calculates the same HMAC. If the values differ, the server rejects the request.</p>



<pre class="wp-block-code"><code>Var sharedSecret As String = "replace-this-with-a-real-secret"
Var requestText As String = "POST|/api/orders|1714492800|{""id"":42}"
Var requestData As MemoryBlock = requestText
Var signature As MemoryBlock = Crypto.HMAC(sharedSecret, requestData, Crypto.HashAlgorithms.SHA2_256)
Var signatureText As String = EncodeBase64(signature)</code></pre>



<p>Send&nbsp;<code>requestText</code>&nbsp;and&nbsp;<code>signatureText</code>&nbsp;to the server. The server must build exactly the same text before calculating its own signature. A different separator, line ending, or JSON layout produces a different result.</p>



<p>A signature by itself does not stop somebody from sending the same valid request again. Include a timestamp and reject requests that are too old. For an operation that must only happen once, include a unique request ID and record IDs that the server has already processed.</p>



<p>HMAC is a good fit for two backend services or a controlled client-server arrangement. It is a poor fit when you ship the shared secret inside an untrusted desktop or mobile app. A secret compiled into an app can eventually be extracted.</p>



<h2 class="wp-block-heading" id="example-4-verifying-an-update-with-ed25519">Example 4: Verifying an update with Ed25519</h2>



<p>A different situation comes up when you distribute application updates. The update server should be able to sign a file, but the installed app should only need to verify it. The installed app should not possess a secret that could create fake signatures.</p>



<p>Use a public and private key pair:</p>



<ul class="wp-block-list">
<li>Keep the private key on the signing machine.</li>



<li>Put the public key in the application or distribute it through a trusted channel.</li>
</ul>



<pre class="wp-block-code"><code>Var privateKey As String
Var publicKey As String

If Crypto.ED25519GenerateKeyPair(privateKey, publicKey) Then
  Var updateInfo As String = "version=4.2.1|sha256=..."
  Var signature As MemoryBlock = Crypto.ED25519Sign(updateInfo, privateKey)

  If signature &lt;&gt; Nil And Crypto.ED25519VerifySignature(updateInfo, signature, publicKey) Then
    MessageBox("Update information is authentic")
  End If
End If</code></pre>



<p>In a real updater, verify the signature before trusting the version or downloading the file. The signature does not prove that the update is safe by itself. It proves that the data matches the private key associated with the public key.</p>



<p>Keep the exact bytes stable. If the signing tool adds a line ending but the app removes it before verification, the signature will fail.</p>



<h2 class="wp-block-heading" id="which-function-solves-which-problem">Which function solves which problem?</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">Problem</th><th class="has-text-align-left" data-align="left">Use</th><th class="has-text-align-left" data-align="left">What you store or send</th></tr></thead><tbody><tr><td>Check a password later</td><td><code>Crypto.PBKDF2</code></td><td>Salt, iteration count, algorithm, derived value</td></tr><tr><td>Create an unpredictable salt or IV</td><td><code>Crypto.GenerateRandomBytes</code></td><td>The salt or IV, when the operation needs it later</td></tr><tr><td>Hide data that your app must decrypt</td><td><code>Crypto.AESEncrypt</code>&nbsp;and&nbsp;<code>Crypto.AESDecrypt</code></td><td>Key, IV, and ciphertext, using a safe storage design</td></tr><tr><td>Detect changes to a shared-secret request</td><td><code>Crypto.HMAC</code></td><td>Message and HMAC value</td></tr><tr><td>Verify data signed by another system</td><td><code>Crypto.ED25519Sign</code>&nbsp;and&nbsp;<code>Crypto.ED25519VerifySignature</code></td><td>Signature and public key</td></tr><tr><td>Create a fixed fingerprint of public data</td><td><code>Crypto.Hash</code></td><td>The expected hash from a trusted source</td></tr></tbody></table></figure>



<p>Start with the problem, not the function name. Ask what the other side needs to do:</p>



<ul class="wp-block-list">
<li>Does it need to check a password? Use PBKDF2.</li>



<li>Does it need to read the original data? Use encryption.</li>



<li>Does it need to detect a changed message and share a secret with the sender? Use HMAC.</li>



<li>Does it need to verify a message without being able to create signatures? Use a public-key signature.</li>
</ul>



<h2 class="wp-block-heading" id="a-short-safety-checklist">A short safety checklist</h2>



<ol class="wp-block-list">
<li>Never store plaintext passwords.</li>



<li>Do not use a fast general-purpose hash as a password-storage scheme.</li>



<li>Do not hard-code production secrets in source code or a desktop application.</li>



<li>Generate salts and IVs with&nbsp;<code>Crypto.GenerateRandomBytes</code>.</li>



<li>Use&nbsp;<code>SHA2_256</code>&nbsp;or stronger for new hashes and HMACs. Avoid MD5 and SHA-1 for new security designs.</li>



<li>Do not treat AES-CBC ciphertext as authenticated unless you add an integrity check.</li>



<li>Keep the exact bytes being signed stable.</li>



<li>Test wrong passwords, wrong keys, changed messages, replayed requests, and corrupted ciphertext.</li>



<li>Check the Xojo compatibility notes for every algorithm you choose.</li>



<li>Use an established format or library instead of inventing a cryptographic protocol.</li>
</ol>



<p>The&nbsp;<code>Crypto</code>&nbsp;module gives you the operations. Your application still has to decide where keys live, what gets signed, how data is formatted, and how keys are replaced. Those decisions determine whether the example can grow into something you can support.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to code-sign Windows apps, including an automation script</title>
		<link>https://blog.xojo.com/2026/08/26/how-to-code-sign-windows-apps-including-an-automation-script/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Wed, 26 Aug 2026 16:03:14 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[azure-artifact]]></category>
		<category><![CDATA[code-signing]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16459</guid>

					<description><![CDATA[You build a Windows app, zip it up, hand it to a user, and Windows may hit them with&#160;&#8220;Windows protected your PC&#8221;. A clean but&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You build a Windows app, zip it up, hand it to a user, and Windows may hit them with&nbsp;<em>&#8220;Windows protected your PC&#8221;</em>. A clean but unsigned binary has no publisher identity or established SmartScreen reputation, so Windows has little reason to trust it.</p>



<p>This guide walks you through the complete process of signing EXE and DLL files on Windows with&nbsp;<strong>Azure Artifact Signing</strong>.</p>



<p>Here&#8217;s the shape of it, so you know what you&#8217;re signing up for:</p>



<ul class="wp-block-list">
<li><strong>One-time setup (Steps 1–9):</strong>&nbsp;Azure account, portal clicks, and identity validation. This is the slow part. Budget a day to a week for the identity check to clear.</li>



<li><strong>Every build (Step 10):</strong>&nbsp;one script that signs your exe and DLLs in seconds.</li>
</ul>



<p>If you&#8217;ve already done the setup, skip straight to&nbsp;Step 10.</p>



<h2 class="wp-block-heading" id="why-i-picked-azure-artifact-signing">Why I Picked Azure Artifact Signing</h2>



<ul class="wp-block-list">
<li><strong>$9.99/mo</strong>&nbsp;for up to 5,000 signatures (Basic tier), with no USB hardware token to manage.</li>



<li><strong>Fully managed.</strong>&nbsp;Microsoft rotates the certificates daily behind the scenes. You never see or store a private key.</li>



<li><strong>Identity-based publisher reputation.</strong>&nbsp;Public Trust signing ties the signature to your validated identity instead of a certificate you manage yourself. SmartScreen warnings can still appear for first-time or low-volume downloads; signing does not guarantee they will disappear immediately.</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>A note on names:</strong>&nbsp;this service was called &#8220;Azure Trusted Signing&#8221; until recently. Same thing, new name. If you see &#8220;Trusted Signing&#8221; in older docs or screenshots, it&#8217;s the same service.</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="prerequisites">Prerequisites</h2>



<ol class="wp-block-list">
<li>A Microsoft account (you get one when you sign up with Azure).</li>



<li>A&nbsp;<strong>paid Azure subscription.</strong>&nbsp;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> This is the #1 early blocker: Artifact Signing&nbsp;<strong>does not work on free/trial/sponsored subscriptions.</strong>&nbsp;Upgrade to&nbsp;<strong>pay-as-you-go</strong>&nbsp;first (Cost Management + Billing → your subscription → upgrade) &#8211;&nbsp;<a href="https://azure.microsoft.com/en-us/products/artifact-signing" target="_blank" rel="noreferrer noopener">https://azure.microsoft.com/en-us/products/artifact-signing</a>.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-1--register-the-resource-provider">Step 1 — Register the resource provider</h2>



<p>Quick orientation first: an Azure&nbsp;<strong>subscription</strong>&nbsp;is the billing container for everything you create. Azure charges your services to it, and it also defines where those resources live and who can access them. When you signed up, Azure created one for you automatically (often with a forgettable default name like &#8220;Azure subscription 1&#8221;).</p>



<p>A separate subscription is optional. If you want clean billing and access boundaries for signing, create or dedicate one; otherwise, use your existing paid subscription and keep the signing resources in a dedicated resource group.</p>



<p>Then:</p>



<ol class="wp-block-list">
<li>Portal →&nbsp;<strong>Subscriptions</strong>&nbsp;→ the subscription you chose.</li>



<li>Left menu →&nbsp;<strong>Settings → Resource providers</strong>.</li>



<li>Find&nbsp;<strong><code>Microsoft.CodeSigning</code></strong>&nbsp;→ click the&nbsp;<strong>…</strong>&nbsp;→&nbsp;<strong>Register</strong>. Wait for&nbsp;<strong>Registered</strong>.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-2--create-the-artifact-signing-account">Step 2 — Create the Artifact Signing account</h2>



<p>Keep the signing resources together in the same subscription and a dedicated resource group.</p>



<ol class="wp-block-list">
<li>Portal search →&nbsp;<strong>Artifact Signing Accounts → Create</strong>.</li>



<li><strong>Subscription</strong>: the paid subscription you chose.&nbsp;<strong>Resource group</strong>: new, e.g.&nbsp;<code>rg-artifact-signing</code>.</li>



<li><strong>Account name</strong>: 3–24 alphanumeric, starts with a letter,&nbsp;<strong>globally unique</strong>&nbsp;(no consecutive hyphens). e.g.&nbsp;<code>xojoappsigning</code>.</li>



<li><strong>Region</strong>: pick one you&#8217;ll remember; it determines your signing endpoint.</li>



<li><strong>Pricing</strong>:&nbsp;<strong>Basic</strong>&nbsp;unless you&#8217;ll exceed 5,000 signs/month.</li>



<li>Create, then note the&nbsp;<strong>Account URI</strong>&nbsp;on the overview page. It follows the pattern&nbsp;<code>https://&lt;region-code&gt;.codesigning.azure.net/</code>.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-3--assign-the-identity-verifier-role">Step 3 — Assign the Identity Verifier role</h2>



<p>You need this before the identity-validation button becomes clickable.</p>



<ol class="wp-block-list">
<li>From your Artifact Signing account, left menu →&nbsp;<strong>Access control (IAM)</strong>&nbsp;→&nbsp;<strong>Add role assignment</strong>.</li>



<li>Role:&nbsp;<strong>Artifact Signing Identity Verifier</strong>&nbsp;(use the search field) → assign to&nbsp;<strong>your own user account</strong>.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-4--identity-validation-the-real-gate">Step 4 — Identity validation (the real gate)</h2>



<p>From your Artifact Signing account (the one you created in Step 2), go to the left menu →&nbsp;<strong>Objects → Identity validations</strong>&nbsp;→&nbsp;<strong>New Identity</strong>&nbsp;→&nbsp;<strong>Public</strong>.</p>



<p><strong>Public</strong>&nbsp;is what you want for normal app signing (it&#8217;s what SmartScreen cares about).</p>



<p>Fill in your legal business name, website, emails, business identifier (tax ID / DUNS), and address. Two gotchas that bite everyone:</p>



<ul class="wp-block-list">
<li>The&nbsp;<strong>secondary email must be on the same domain as the primary</strong>.</li>



<li><strong>Individual developers</strong>: the form pulls from your Azure&nbsp;<em>billing account</em>, and its name/address must exactly match your ID.</li>
</ul>



<p><strong>What happens next:</strong>&nbsp;status goes&nbsp;<code>In Progress</code>&nbsp;→&nbsp;<code>Action Required</code>&nbsp;(this is the point when you may have to wait a few hours to days&#8230; In my case, it took only an hour). You&#8217;ll be routed through a third-party verifier (<strong>AU10TIX</strong>). You upload a government ID and a selfie from your phone, then add the resulting&nbsp;<strong>Verified ID to Microsoft Authenticator</strong>&nbsp;and share it back (another hour or so).</p>



<p><strong>Timeline:</strong>&nbsp;officially 1–20 business days; in practice often hours to a few days. If it stalls, re-submit with a different identifier (tax ID instead of DUNS) and make sure your company name/address match your documents&nbsp;<em>exactly</em>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-5--create-the-certificate-profile">Step 5 — Create the certificate profile</h2>



<ol class="wp-block-list">
<li>From your Artifact Signing account, left menu →&nbsp;<strong>Objects → Certificate profiles</strong>&nbsp;→&nbsp;<strong>Create</strong>.</li>



<li>Type:&nbsp;<strong>Public Trust</strong>.</li>



<li>Name it (5–100 chars), then pick your completed identity validation under&nbsp;<strong>Verified CN and O</strong>.</li>



<li>Create. You never see or hold the certificate. It&#8217;s rotated daily behind the scenes. The public cert is embedded in every file you sign.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-6--assign-the-certificate-profile-signer-role">Step 6 — Assign the Certificate Profile Signer role</h2>



<p>This is the role that lets you actually sign. Because we&#8217;re using the Azure CLI, it goes on&nbsp;<strong>your user</strong>. No app registration is needed (this is a separate/alternative process, but we&#8217;re not talking about that in this article).</p>



<ol class="wp-block-list">
<li>From your Artifact Signing account, left menu →&nbsp;<strong>Access control (IAM)</strong>&nbsp;→&nbsp;<strong>Add role assignment</strong>.</li>



<li>Role:&nbsp;<strong>Artifact Signing Certificate Profile Signer</strong>&nbsp;→ assign to&nbsp;<strong>your own user account</strong>.</li>
</ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Give role assignments a few minutes to propagate. If you try signing immediately and hit a 403, wait ~5 minutes and retry.</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-7--install-the-signing-tools">Step 7 — Install the signing tools</h2>



<p>First, the <strong>Azure CLI</strong>: <code>winget install Microsoft.AzureCLI</code></p>



<p><em>You’ll use it in Step 9 to authenticate with Azure.</em></p>



<p><strong>SignTool</strong>&nbsp;comes with the Windows SDK. Install it with: <code>winget install --id Microsoft.WindowsSDK --exact</code></p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;Run this to find the newest x64&nbsp;signtool.exe:<br><code>Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin" -Recurse -Filter signtool.exe | Where-Object { $_.FullName -match '\\x64\\signtool\.exe$' } | Sort-Object FullName -Descending | Select-Object -First 1 -ExpandProperty FullName</code></p>



<p><em>Note the path down.</em></p>



<p><strong>.NET 8 runtime</strong>&nbsp;(x64).</p>



<p><strong>Microsoft Visual C++ Redistributable</strong>.</p>



<p><strong>Artifact Signing Client Tools</strong>:<code>winget install -e --id Microsoft.Azure.ArtifactSigningClientTools</code><br>This installs&nbsp;<code>Azure.CodeSigning.Dlib.dll</code>&nbsp;(the plugin signtool uses to talk to Azure).</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;Locate the actual dll path after install:<br><code>Get-ChildItem -Path "C:\Program Files","$env:LOCALAPPDATA" -Recurse -Filter Azure.CodeSigning.Dlib.dll -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName</code></p>



<p><em>Note the path down.</em></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>If&nbsp;<code>signtool</code>&nbsp;gives you &#8220;command not found&#8221;, that&#8217;s normal; it&#8217;s not on PATH. Use the full path, or add&nbsp;<code>...\10\&lt;version&gt;\x64</code>&nbsp;to your PATH.</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-8--create-the-metadata-file">Step 8 — Create the metadata file</h2>



<p>This is a small JSON with three values. Name it anything you like, e.g.&nbsp;<code>artifact-code-signing.json</code>:</p>



<pre class="wp-block-code"><code>{
	"Endpoint": "https://&lt;region-code&gt;.codesigning.azure.net",
	"CodeSigningAccountName": "xojoappsigning",
	"CertificateProfileName": "...."
}</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>This JSON file will be used a lot, so save it somewhere safe.</p>
</blockquote>



<ul class="wp-block-list">
<li><strong>Endpoint</strong>&nbsp;= your account URI (region-specific; must match where the account + profile live, or you get a 403).</li>



<li><strong>CodeSigningAccountName</strong>&nbsp;= the Artifact Signing account name from Step 2.</li>



<li><strong>CertificateProfileName</strong>&nbsp;= the certificate profile name you created in Step 5.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-9--authenticate-with-the-azure-cli">Step 9 — Authenticate with the Azure CLI</h2>



<pre class="wp-block-code"><code>az login</code></pre>



<p>This opens your browser; sign in with the Microsoft account tied to your Azure subscription. When signtool runs, the dlib picks up your logged-in Azure CLI session automatically.</p>



<p>If you have multiple Azure subscriptions, point the CLI at the right one, then confirm it took:</p>



<pre class="wp-block-code"><code>az account set --subscription "&lt;your subscription id&gt;"
az account show --query name -o tsv</code></pre>



<p>The second command should print your code-signing subscription&#8217;s name. If you also have multiple Microsoft tenants (a personal account&nbsp;<em>and</em>&nbsp;a work account, for example), log straight into the right one:</p>



<pre class="wp-block-code"><code>az login --tenant "&lt;tenant id&gt;"</code></pre>



<p>You may occasionally need to re-run&nbsp;<code>az login</code>&nbsp;after long idle periods.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="step-10--sign-your-xojo-app">Step 10 — Sign your Xojo app</h2>



<p>Just remember, you need to&nbsp;<strong>sign the compiled application after each new build</strong>.</p>



<h3 class="wp-block-heading" id="what-to-sign-and-skip">What to sign (and skip)</h3>



<p>Your Xojo Windows build folder looks roughly like this. Sign the binaries you build or distribute under your publisher identity; leave Xojo, Microsoft, and other vendor-signed dependencies alone.</p>



<pre class="wp-block-code"><code>Windows 64 bit/
└── YourApp/
    ├── YourApp.exe              ← sign
    ├── &lt;your own DLLs&gt;          ← sign
    ├── XojoGUIFramework64.dll   ← skip, Xojo provides signed DLLs
    ├── YourApp Libs/            ← skip, Xojo provides signed DLLs
    ├── msvcp140.dll, vcruntime*.dll …  ← skip (Microsoft runtime)
    └── YourApp.exe.WebView2/    ← skip (WebView2 cache)
</code></pre>



<h3 class="wp-block-heading" id="the-script">The script</h3>



<p>Save this as&nbsp;<code>sign.ps1</code>, next to the Xojo project, update the paths at the top, and run it from PowerShell:</p>



<pre class="wp-block-code"><code>$ErrorActionPreference = "Stop"

$Signtool    = "C:\...\signtool.exe"                            <em># path from Step 7</em>
$Dlib        = "C:\...\Azure.CodeSigning.Dlib.dll"              <em># path from Step 7</em>
$Metadata    = "C:\...\artifact-code-signing.json"              <em># from Step 8</em>
$BuildFolder = "F:\...\YourApp"                                 <em># folder containing YourApp.exe</em>

<em># Installer (Inno Setup) — optional. Set $EnableInno to $false to skip this part.</em>
$EnableInno  = $true
$InnoSetup   = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
$IssScript   = "F:\...\YourAppSetup.iss"                        <em># your Inno Setup script</em>
$Installer   = "F:\...\YourAppSetup.exe"                        <em># output from the .iss</em>

<em># Sign binaries you build or distribute under your publisher identity.</em>
<em># Leave Xojo, Microsoft, and other vendor-signed dependencies alone.</em>
$FilesToSign = @(
    "$BuildFolder\YourApp.exe"
    "$BuildFolder\MyPlugin.dll"
    <em># add any other files you own here, one per line</em>
)

function Invoke-SigningCommand {
    param(&#91;string&#91;]]$Arguments)

    &amp; $Signtool @Arguments
    if ($LASTEXITCODE -ne 0) {
        throw "SignTool failed with exit code $LASTEXITCODE."
    }
}

foreach ($f in $FilesToSign) {
    Invoke-SigningCommand @(
        "sign", "/v", "/fd", "SHA256",
        "/tr", "http://timestamp.acs.microsoft.com", "/td", "SHA256",
        "/dlib", $Dlib, "/dmdf", $Metadata,
        $f
    )
}

if ($EnableInno) {
    <em># Build a fresh installer, then sign it.</em>
    &amp; $InnoSetup $IssScript
    if ($LASTEXITCODE -ne 0) {
        throw "Inno Setup failed with exit code $LASTEXITCODE."
    }

    Invoke-SigningCommand @(
        "sign", "/v", "/fd", "SHA256",
        "/tr", "http://timestamp.acs.microsoft.com", "/td", "SHA256",
        "/dlib", $Dlib, "/dmdf", $Metadata,
        $Installer
    )
}</code></pre>



<p>What the flags mean:</p>



<ul class="wp-block-list">
<li><code>/tr http://timestamp.acs.microsoft.com</code>: the timestamp server. The&nbsp;<code>http://</code>&nbsp;(not https) is intentional.</li>



<li><code>/fd SHA256</code>&nbsp;and&nbsp;<code>/td SHA256</code>: SHA-256 for the file and the timestamp.</li>



<li><code>/dlib</code>: the Azure plugin from Step 7.&nbsp;<code>/dmdf</code>: your metadata JSON from Step 8.</li>
</ul>



<h3 class="wp-block-heading" id="confirm-it-worked">Confirm it worked</h3>



<p>Two checks:</p>



<ol class="wp-block-list">
<li><strong>Signtool:</strong><code>$Signtool verify /v /pa "$BuildFolder\YourApp.exe" </code>You want to see&nbsp;<code>Successfully verified</code>.</li>



<li><strong>Or:</strong>&nbsp;right-click&nbsp;<code>YourApp.exe</code>&nbsp;→&nbsp;<strong>Properties → Digital Signatures</strong>&nbsp;→ your org name should be listed.</li>
</ol>



<h3 class="wp-block-heading" id="rules-of-thumb">Rules of thumb</h3>



<ul class="wp-block-list">
<li><strong>Sign after every build.</strong>&nbsp;Each new&nbsp;<code>.exe</code>&nbsp;is a fresh unsigned binary.</li>



<li><strong>Sign before you zip.</strong>&nbsp;Sign the files,&nbsp;<em>then</em>&nbsp;package them. Signing inside a zip does nothing.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="troubleshooting">Troubleshooting</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">Symptom</th><th class="has-text-align-left" data-align="left">Fix</th></tr></thead><tbody><tr><td><code>signtool: command not found</code></td><td>Use the full SDK path; it&#8217;s not on PATH</td></tr><tr><td><code>No certificates were found</code></td><td>dlib path wrong, or x86/x64 mismatch between signtool and dlib</td></tr><tr><td><code>403 Forbidden</code></td><td>Signer role on the wrong account, wrong account name in JSON, or endpoint/region mismatch</td></tr><tr><td><code>SignTool Error: An unexpected internal error</code></td><td>Update signtool to ≥ 10.0.22621.755; check .NET 8 + VC++ redist</td></tr><tr><td>Signing appeared to succeed, but no signature is visible</td><td>Run&nbsp;<code>signtool verify /v /pa &lt;file&gt;</code>; its exit code and&nbsp;<code>Successfully verified</code>&nbsp;output are authoritative. Explorer&#8217;s Digital Signatures tab is not available for every file type.</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="recap">Recap</h2>



<p><strong>One time (Steps 1–9):</strong>&nbsp;register the&nbsp;<code>Microsoft.CodeSigning</code>&nbsp;provider → create the account → assign the Identity Verifier role → complete identity validation (slow&#8217;ish) → create the certificate profile → assign the Signer role → install tools → write the metadata JSON →&nbsp;<code>az login</code>.</p>



<p><strong>Every build (Step 10):</strong>&nbsp;run&nbsp;<code>sign.ps1</code>.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="the-bottom-line">The bottom line</h2>



<p>Azure Artifact Signing is a low-cost managed option for signing Windows apps, and Azure CLI authentication means local builds do not need a stored signing private key. The setup has some Azure bureaucracy, and identity validation is the slow part. After that, it is one script per build.</p>



<h4 class="wp-block-heading">Related discussion</h4>



<p>For an alternative approach that automates Xojo application signing and Inno Setup installer creation, see Jürg Otter’s Xojo Forum topic, <a href="https://forum.xojo.com/t/windows-code-signing-installer-creation-with-innosetup/84732" target="_blank" rel="noreferrer noopener">Windows Code Signing &amp; Installer Creation with Inno Setup</a>. The topic includes Jürg’s open-source code, which supports both Azure Artifact Signing and traditional <code>.pfx</code> certificates.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Quick Tip: Place limits on MobileImagePicker</title>
		<link>https://blog.xojo.com/2026/08/20/quick-tip-place-limits-on-mobileimagepicker/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 20 Aug 2026 10:00:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[MobileImagePicker]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16441</guid>

					<description><![CDATA[The MobileImagePicker class has been around for while. It lets users take photos using a device&#8217;s available cameras and choose images from the device gallery.&#8230;]]></description>
										<content:encoded><![CDATA[<p>The MobileImagePicker class has been around for while. It lets users take photos using a device&#8217;s available cameras and choose images from the device gallery.<span id="more-16441"></span></p>


<p>The class has been improved through several Xojo releases, offering more options and modernizing its look and feel to match recent iOS releases. In this post, let&#8217;s talk about using one of those small but useful improvements to MobileImagePicker with Xojo 2026r2, the <code>SelectionLimit</code> property.</p>



<p>On previous releases, when using the <a href="https://documentation.xojo.com/api/user_interface/mobile/mobileimagepicker.html#mobileimagepicker"><code>MobileImagePicker</code></a> to select pictures from the device gallery (using <code>MobileImagePicker.Sources.Photos</code>), the user was allowed to choose as many pictures as they wanted to…&nbsp;but maybe that was not what your app logic expected!</p>



<p>Now you can use <code>MobileImagePicker.SelectionLimit</code> to set that expectation, so the user must comply with the limits your app needs.</p>



<p>If the logic of any of your existing apps allows the user to select as many pictures as they want, then there is nothing you need to do, the existing code will continue to work as expected. That is because the default value of the <code>MobileImagePicker.SelectionLimit</code> is 0. Or if you want to be more explicit, you can set the property to <code>MobileImagePicker.UnlimitedSelection</code>.</p>



<p>When setting the <code>MobileImagePicker.SelectionLimit</code> property to any other value, the iOS modal dialog will display that limit to the user so they know exactly what is expected.</p>



<p>Do you want to see it in action? Open the iOS &gt; ImagePicker example project from the IDE. Once opened, select the <code>Pressed</code> event handler from the Button1 item in the project navigator to access the associated Code Editor. Then, modify the existing code like this:</p>



<pre class="wp-block-code"><code>ImagePicker.Source = MobileImagePicker.Sources.Photos
ImagePicker.SelectionLimit = 2
ImagePicker.Show()</code></pre>



<p>We set the maximum limit of selected images to two. Run the app in the simulator, click on the Pick Pictures button, and the following modal will be shown, allowing you to choose a maximum of two images:</p>



<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-16442" src="https://blog.xojo.com/wp-content/uploads/2026/08/Simulator-Screenshot-iPhone-14-Pro-2026-08-17-at-11.08.51.png" alt="" width="1179" height="1323" srcset="https://blog.xojo.com/wp-content/uploads/2026/08/Simulator-Screenshot-iPhone-14-Pro-2026-08-17-at-11.08.51.png 1179w, https://blog.xojo.com/wp-content/uploads/2026/08/Simulator-Screenshot-iPhone-14-Pro-2026-08-17-at-11.08.51-267x300.png 267w, https://blog.xojo.com/wp-content/uploads/2026/08/Simulator-Screenshot-iPhone-14-Pro-2026-08-17-at-11.08.51-913x1024.png 913w, https://blog.xojo.com/wp-content/uploads/2026/08/Simulator-Screenshot-iPhone-14-Pro-2026-08-17-at-11.08.51-768x862.png 768w" sizes="auto, (max-width: 1179px) 100vw, 1179px" /></p>


<h2>In summary</h2>
<p>Alongside the big features highlighted in each Xojo release, there are a lot of other improvements and helpful additions. Take a look at the full list of updates in the <a href="https://documentation.xojo.com/resources/release_notes/2026r2.html">Release Notes</a>.</p>


<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Change the Font Across Your Entire Application</title>
		<link>https://blog.xojo.com/2026/07/20/change-the-font-across-your-entire-application/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Mon, 20 Jul 2026 12:26:28 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Cross-Platform Development]]></category>
		<category><![CDATA[DesktopContainer]]></category>
		<category><![CDATA[DesktopWindow]]></category>
		<category><![CDATA[FontName]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16426</guid>

					<description><![CDATA[While working on one of my Xojo projects, I needed a quick way to change the font used by the controls across the entire application.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>While working on one of my Xojo projects, I needed a quick way to change the font used by the controls across the entire application.</p>



<p>Opening every window and updating each control individually works, but it gets tedious quickly, especially when testing different fonts or adding new UI elements. So I created a small module that applies a font to all supported controls in a <code>DesktopWindow</code>, including controls placed inside <code>DesktopContainer</code> instances.</p>



<pre class="wp-block-code"><code>Module AppWideFont
  Public Sub SetFont(Extends window As DesktopWindow, fontName As String)
    ApplyFontTo(window.Controls, fontName)
  End Sub

  Protected Function GetMonospaceFont() As String
    #If TargetWindows
      Return "Cascadia Mono"
    #ElseIf TargetMacOS
      Return "Menlo"
    #ElseIf TargetLinux
      Return "DejaVu Sans Mono"
    #Else
      Return "Courier New"
    #EndIf
  End Function

  Private Sub ApplyFontTo(controls As Iterable, fontName As String)
    For Each c As Object In controls
      If c IsA DesktopContainer Then
        ApplyFontTo(DesktopContainer(c).Controls, fontName)
      End If
      
      Select Case c
      Case IsA DesktopLabel
        DesktopLabel(c).FontName = fontName
      Case IsA DesktopTextField
        DesktopTextField(c).FontName = fontName
      Case IsA DesktopTextArea
        DesktopTextArea(c).FontName = fontName
      Case IsA DesktopListBox
        DesktopListBox(c).FontName = fontName
      Case IsA DesktopButton
        DesktopButton(c).FontName = fontName
      Case IsA DesktopCheckBox
        DesktopCheckBox(c).FontName = fontName
      Case IsA DesktopRadioButton
        DesktopRadioButton(c).FontName = fontName
      Case IsA DesktopPopupMenu
        DesktopPopupMenu(c).FontName = fontName
      End Select
    Next
  End Sub

End Module</code></pre>



<p>The&nbsp;<code>SetFont</code>&nbsp;method is an extension method, so I can call it directly on any&nbsp;<code>DesktopWindow</code>.</p>



<p>For example, in a window’s&nbsp;<code>Opening</code>&nbsp;event:</p>



<pre class="wp-block-code"><code><strong>Self</strong>.<strong>SetFont</strong>("Arial")</code></pre>



<p>Or, if I want to use a monospace font:</p>



<pre class="wp-block-code"><code><strong>Self</strong>.<strong>SetFont</strong>(AppWideFont.GetMonospaceFont)</code></pre>



<p>The&nbsp;<code>GetMonospaceFont</code>&nbsp;function is just a simple additional helper that returns a suitable monospace font for Windows, macOS, or Linux.</p>



<p>The module uses the window’s&nbsp;<code>Controls</code>&nbsp;collection and recursively checks any&nbsp;<code>DesktopContainer</code>&nbsp;controls, so I only need one line of code per window. It currently handles labels, text fields, text areas, list boxes, buttons, checkboxes, radio buttons, and popup menus.</p>



<p>If I add another control type later, I can extend the&nbsp;<code>Select Case</code>&nbsp;statement with another branch.</p>



<p>This saved me from repeatedly changing font settings throughout the project and gave me one central place to control the application’s typography.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Web in 2026r2: Faster, Smarter, SEO-Ready</title>
		<link>https://blog.xojo.com/2026/07/08/xojo-web-in-2026r2-faster-smarter-seo-ready/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 15:40:00 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2026r2]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16392</guid>

					<description><![CDATA[Performance has taken a great leap forward, SEO support lands properly this time around, and there are a handful of quality-of-life improvements that will make&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Performance has taken a great leap forward, SEO support lands properly this time around, and there are a handful of quality-of-life improvements that will make your daily coding a bit smoother. Let&#8217;s dig in.</p>



<h2 class="wp-block-heading">Performance: Beyond 13,000 Requests Per Second</h2>



<p>If you have been following the web framework&#8217;s performance numbers over the releases, you know they have been steadily improving. In 2024r2, benchmarks were sitting at around 8-9k requests per second. In 2026r2, we are beyond 13k. That is a significant jump, and it comes from a fundamental change in how the framework handles connections under the hood.</p>



<p>Xojo Web is essentially a Console project built on top of&nbsp;<code>ServerSocket</code>&nbsp;and&nbsp;<code>TCPSocket</code>. Previously, each incoming connection would spawn a new&nbsp;<code>Thread</code>, process the request, and then that thread would be destroyed. In 2026r2, threads are created when the&nbsp;<code>TCPSocket</code>&nbsp;is created, before the connection even arrives. When a request comes in, the thread is already there, sleeping, waiting. No need to spin one up from scratch. And when a&nbsp;<code>TCPSocket</code>&nbsp;can be reused, so can its thread, meaning fewer kernel calls and less overhead overall.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="586" src="https://blog.xojo.com/wp-content/uploads/2026/06/Captura-de-pantalla-2026-06-24-a-las-12.18.06-1024x586.png" alt="" class="wp-image-16394" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/Captura-de-pantalla-2026-06-24-a-las-12.18.06-1024x586.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/06/Captura-de-pantalla-2026-06-24-a-las-12.18.06-300x172.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/Captura-de-pantalla-2026-06-24-a-las-12.18.06-768x440.png 768w, https://blog.xojo.com/wp-content/uploads/2026/06/Captura-de-pantalla-2026-06-24-a-las-12.18.06-1536x880.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/06/Captura-de-pantalla-2026-06-24-a-las-12.18.06-2048x1173.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>That said, even with a 50% increase in this benchmark, most developers won&#8217;t notice a big difference. When the application has to deal with frequent database queries, for example, shaving a few milliseconds off request handling is a drop in the bucket. But where it does matter, it matters a lot. If your application is a plain REST API serving data for a mobile app with thousands of concurrent users, or when it is deployed to a constrained environment like a Raspberry Pi, this kind of improvement can make a real difference.</p>



<h2 class="wp-block-heading">SEO Improvements Done Right</h2>



<p>In 2026r1 we introduced the ability to call&nbsp;<code>WebPage.Show</code>&nbsp;from within the&nbsp;<code>HandleURL</code>&nbsp;event, which opened the door for serving pages to search engine crawlers. It worked, but it came with a significant cost: even for users who were not using this feature at all, benchmark numbers dropped from 7-8k requests per second down to 1-2k. That was not acceptable (pushing us to review the overall web framework performance on this release), and it also introduced edge cases for codebases that expected&nbsp;<code>HandleURL</code>&nbsp;to run without any session context active, because creating a session context on top of an existing one is not allowed.</p>



<p>In 2026r2, this is fixed properly. The performance penalty is gone for everyone. If you want to use&nbsp;<code>WebPage.Show</code>&nbsp;from&nbsp;<code>HandleURL</code>&nbsp;for SEO purposes, you now opt in explicitly by creating a&nbsp;<code>WebSessionContext</code>&nbsp;instance yourself, passing the <code>request</code>parameter, before calling&nbsp;<code>Show</code>. It is a small step, but it makes the intent clear and keeps things safe for everyone else.</p>



<p><code>WebSessionContext</code> has a new <code>Constructor</code>, accepting a <code>request As WebRequest</code> parameter.</p>



<p>We are not stopping here. SEO is important, and we are already working on a proper URL router to make these workflows easier and more capable. Stay tuned!</p>



<h2 class="wp-block-heading">DatabaseConnection Gets a PerSession Mode</h2>



<p>If you use a&nbsp;<a href="https://documentation.xojo.com/topics/databases/connecting_to_a_database.html" target="_blank" rel="noreferrer noopener">Database Connection</a>&nbsp;in your web project, you are probably familiar with how they work: you add one to your project in the Navigator, give it a name, say&nbsp;<code>MyDatabaseConnection</code>, and then you reference it by that name anywhere in your code to run queries.</p>



<p>By default, that connection behaves like a singleton. Every session in your web app shares the same&nbsp;<code>MyDatabaseConnection</code>instance. For most read-only usage that is fine, but the moment you start using transactions, you can run into trouble. One session&#8217;s transaction can interfere with another&#8217;s, or worse, data from one session can leak into another&#8217;s results.</p>



<p>The new&nbsp;<code>PerSession</code>&nbsp;property in 2026r2 solves this at design time. When you enable it in the Inspector,&nbsp;<code>MyDatabaseConnection</code>stops being a shared instance. Instead, each session gets its own connection, created lazily the first time that session needs it, and automatically destroyed when the session ends. Your code does not change, you still write&nbsp;<code>MyDatabaseConnection.SelectSQL(...)</code>&nbsp;as you always have, but now you can be confident each session is operating in complete isolation.</p>



<h2 class="wp-block-heading">WebGraphics Gets DrawPath and FillPath</h2>



<p><code>WebGraphics</code>&nbsp;now supports&nbsp;<code>DrawPath</code>&nbsp;and&nbsp;<code>FillPath</code>, bringing it in line with what Desktop and Mobile targets have had for a while. If you have been writing custom drawing code for other targets using&nbsp;<code>Graphics.DrawPath</code>&nbsp;or&nbsp;<code>Graphics.FillPath</code>, that code can now be reused in your web projects without modification.</p>



<p>This is exactly the kind of cross-target parity that makes Xojo powerful. Check the&nbsp;<a href="https://documentation.xojo.com/api/graphics/webgraphics.html" target="_blank" rel="noreferrer noopener">WebGraphics documentation</a>&nbsp;for the full details on how paths work.</p>



<h2 class="wp-block-heading">WebImageViewer: Goodbye, Flicker</h2>



<p>A small but welcome fix. When updating the&nbsp;<code>Picture</code>&nbsp;property on a&nbsp;<code>WebImageViewer</code>, previous versions would show a brief but noticeable blink, the image would disappear for a few milliseconds before the new one appeared. In 2026r2, the new image is shown directly. No blink, no flicker. It just works.</p>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p>As usual, 2026r2 also includes a solid round of bug fixes across the web framework. Check the&nbsp;<a href="https://documentation.xojo.com/resources/release_notes/2026r2.html" target="_blank" rel="noreferrer noopener">full release notes</a>&nbsp;for the complete list. This is a release that delivers on multiple fronts: raw performance, correctness, cross-target parity, and laying better groundwork for SEO. The thread handling changes alone make this a compelling update for anyone running Xojo web apps under load. And with a proper URL router on the horizon, the SEO story is only going to get better.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://x.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Improved macOS App Debugging Experience</title>
		<link>https://blog.xojo.com/2026/07/08/improved-macos-apps-debugging-experience/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 13:47:00 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2026r2]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Hardened Runtime]]></category>
		<category><![CDATA[Mac App Store]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[Sandboxing]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16345</guid>

					<description><![CDATA[During the last few Xojo releases we have been improving the signing options for macOS apps, making it easier to meet Apple&#8217;s requirements both for&#8230;]]></description>
										<content:encoded><![CDATA[
<p>During the last few Xojo releases we have been improving the signing options for macOS apps, making it easier to meet Apple&#8217;s requirements both for direct distribution of your apps or for Mac App Store distribution. Still, there remained a discrepancy when debugging from the IDE: sandboxing, hardened runtime and the use of entitlements and provisioning profiles were not applied, so there could be a difference between the app you debug and the real behavior of the distributed app.</p>



<span id="more-16345"></span>



<p>The good news is starting with Xojo 2026r2, your debugged macOS apps will exhibit the same behavior your users expect when the app is distributed. For example, if you use sandboxing and hardened runtime, these will be applied. Thus, all the regular operations dealing with files will occur in the sandboxed environment and will meet the settings made under the Build Settings > macOS > Sign > Sandbox panel. This same applies when hardened runtime is selected.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="2504" height="1804" src="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.46.11-PM.png" alt="" class="wp-image-16346" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.46.11-PM.png 2504w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.46.11-PM-300x216.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.46.11-PM-1024x738.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.46.11-PM-768x553.png 768w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.46.11-PM-1536x1107.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.46.11-PM-2048x1475.png 2048w" sizes="auto, (max-width: 2504px) 100vw, 2504px" /></figure>
</div>


<p>In addition, especially for more advanced macOS apps that need to use entitlements and provisioning profiles, these will also be applied when the app is Run / Debug from the Xojo IDE. In this case, make sure to select the Build For > Development Certificate required for signing the app.</p>



<h2 class="wp-block-heading">Debugging with Entitlements in Action</h2>



<p>In order to show how convenient it is to debug macOS apps with entitlements and provisioning profiles applied to them, let&#8217;s make use of one of the small improvements also introduced in Xojo 2026r2: synced KeyChain Passwords. For this to work you will need to have iCloud > Passwords enabled under System Settings > Apple Account > iCloud.</p>



<p>The first step is to create the development provisioning profile from Apple&#8217;s developer portal (specifically for keychain-access-groups), download it and add it to the project using a Copy Build step, making sure that Contents Folder is selected as the destination for the copied file.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1320" height="652" src="https://blog.xojo.com/wp-content/uploads/2026/06/KeyChainAccessGroup.png" alt="" class="wp-image-16347" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/KeyChainAccessGroup.png 1320w, https://blog.xojo.com/wp-content/uploads/2026/06/KeyChainAccessGroup-300x148.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/KeyChainAccessGroup-1024x506.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/06/KeyChainAccessGroup-768x379.png 768w" sizes="auto, (max-width: 1320px) 100vw, 1320px" /></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1536" height="508" src="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-12.55.23-PM.png" alt="" class="wp-image-16348" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-12.55.23-PM.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-12.55.23-PM-300x99.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-12.55.23-PM-1024x339.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-12.55.23-PM-768x254.png 768w" sizes="auto, (max-width: 1536px) 100vw, 1536px" /></figure>
</div>


<p><br></p>



<p>Then, we need to create the associated entitlements file using your favourite text editor for that. Make sure it looks like this for the purpose of this example (you will need to change all the references to the app bundle ID and the Developer ID so these match yours):</p>



<pre class="wp-block-preformatted">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
	&lt;key&gt;keychain-access-groups&lt;/key&gt;
	&lt;array&gt;
		&lt;string&gt;BW7PU32485.*&lt;/string&gt;
	&lt;/array&gt;
	&lt;key&gt;com.apple.application-identifier&lt;/key&gt;
	&lt;string&gt;BW7PU32485.com.aprendexojo.Cheese&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;
</pre>



<p>Once created and saved using the &#8220;.entitlements&#8221; extension, add it to Build Settings > macOS > Sign > User Entitlements.</p>



<h3 class="wp-block-heading">Creating a Synced Password</h3>



<p>After adding a button to the default project Window, implement the Pressed event handler and add this fragment of code into the associated Code Editor:</p>



<pre class="wp-block-preformatted">Var newItem As KeychainItem

If System.KeychainCount &gt; 0 Then

  newItem = New KeychainItem
  newItem.Label = "This is a Label"
  newItem.Description = "This is a description"
  newItem.ServiceName = "MyApplication"
  newItem.AccountName = "XojoTest"
  newItem.Comment = "This is a comment"
  
  ' Assign a password to the item
  ' Passing True as the third parameter means we want this one
  ' to be created / saved under the iCloud keychain,
  ' so it will be automatically synced with other Macs using
  ' the same iCloud user account.
  
  System.Keychain.AddPassword(newItem, "SecretPassword", true)
Else
  System.Beep
  MessageBox("You don't have a key chain.")
End If

Exception e As KeychainException
  MessageBox("Keychain error: " + e.Message)
</pre>



<p>Run the app from the IDE (you can enable both sandboxing and hardened runtime too if you wish), click the button  and it will behave the same way it will when deployed. If you open Keychain Access app, select the iCloud entry in the Keychain window sidebar, and select then the Passwords option you will see the new added password from the debugged app.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1676" height="1290" src="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.29.31-PM.png" alt="" class="wp-image-16349" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.29.31-PM.png 1676w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.29.31-PM-300x231.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.29.31-PM-1024x788.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.29.31-PM-768x591.png 768w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-1.29.31-PM-1536x1182.png 1536w" sizes="auto, (max-width: 1676px) 100vw, 1676px" /></figure>
</div>


<p>Obviously, if you have more than a Mac using the same user iCloud account, you wil be able to see how that password will be synced and added to its Keychain too after a few seconds.</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1818" height="1276" src="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-13.52.52.png" alt="" class="wp-image-16351" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-13.52.52.png 1818w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-13.52.52-300x211.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-13.52.52-1024x719.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-13.52.52-768x539.png 768w, https://blog.xojo.com/wp-content/uploads/2026/06/Screenshot-2026-06-23-at-13.52.52-1536x1078.png 1536w" sizes="auto, (max-width: 1818px) 100vw, 1818px" /></figure>



<p>All in all, this means two things:</p>



<ol class="wp-block-list">
<li>macOS debugged apps exhibit the same behavior expected when these are deployed, which means that you will be able to debug them in more real conditions.</li>



<li>The new ability to create synced passwords is quite convenient for those macOS apps making use of these, so your users won&#8217;t be required to create them again on each of their Macs or create different ones on each Mac they own.</li>
</ol>



<h2 class="wp-block-heading">In Summary</h2>



<p>As we saw, setting sandboxing, hardened runtime, using entitlements and even provisioning profiles in you macOS apps during the debugging process now avoids conditional compilation branches, and provides a closer experience to the final (distributed) app, and even makes it easier to detect bugs in the code.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Improving Copy/Paste with Text</title>
		<link>https://blog.xojo.com/2026/07/08/improving-copy-paste-with-text/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 13:47:00 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[2026r2]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Jade]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16327</guid>

					<description><![CDATA[As you are undoubtedly aware, Xojo does not expose your source code as one big blob of text. That makes it tricky to copy code&#8230;]]></description>
										<content:encoded><![CDATA[
<p>As you are undoubtedly aware, Xojo does not expose your source code as one big blob of text. That makes it tricky to copy code from Xojo or into Xojo from or to outside sources such as blog posts or LLM AI chats. Starting with 2026r2 we&#8217;ve made this easier.</p>



<h2 class="wp-block-heading">Copying</h2>



<p>Copying individual members (methods, properties, etc.) from a project item continues to work as before. However, we have added the ability for you to copy some entire project items out of Xojo as text.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Note</strong>: When copying a project item (or a member), the Navigator, not one of the editors, must have focus. You can tell it has focus by its color, which is non-gray (green on macOS, for example).</p>
</blockquote>



<p>For example, you can select a class (or module or interface) and then paste its contents as text into your favorite text editor, blog editor or AI chat. As an example, here is the DataPoint class (from the Desktop Eddie&#8217;s Electronics example <a href="https://documentation.xojo.com/getting_started/example_projects/eddie's_electronics_sample_app.html">project</a>) copied as text and pasted into this post:</p>



<pre class="wp-block-code"><code>Class DataPoint
  Public Sub Constructor(value as Integer, shape as Integer = 0)
    Self.Value = value
    Self.Shape = shape
  End Sub

  Public Function PointNearby(x as integer, y as integer, tolerance as integer = 10) As Boolean
    If Abs(x-Self.x) &lt; tolerance And Abs(y-Self.y) &lt; tolerance Then
      Return True
    End If
  End Function

  Public Property Label As String

  Public Property Shape As Integer

  Public Property Value As Integer

  Public Property X As Integer

  Public Property Y As Integer

End Class</code></pre>



<p>This is surprisingly handy and is a great way to share your code outside Xojo. You can also select multiple project items at once, plus it works with layouts such as Windows, WebPages, Screens and Containers.</p>



<h2 class="wp-block-heading">Pasting</h2>



<p>Pasting code into Xojo has even more improvements. Previously you could paste single members (Methods, Enums, etc., but not properties) into a project item. Now you can paste multiple members at once, including properties. For example, select and copy the list of properties below and paste them onto a project item.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Note</strong>: When pasting the project item, the Navigator, not one of the editors, must have focus. You can tell it has focus by its color, which is non-gray (green on macOS, for example).</p>
</blockquote>



<pre class="wp-block-code"><code>Public Property Company As String
  Private Property Country As String
Property Address As String
Public Property City As String

Public Property State As String // State code</code></pre>



<p>You can even have different types of members in the selected text, like this:</p>



<pre class="wp-block-code"><code>Public Property Taxable As Boolean
Get
  Const kMax = 42
  Return False
End Get
Set
  Company = "TaxMan”
  Const kMin = 0
End Set
End Property
Public Property Company As String


Public Function Average(A As Double, B As Double) As Double
  Return (A + B) / 2
End Function</code></pre>



<p>And taking things a step further, you can even paste in an entire class:</p>



<pre class="wp-block-code"><code>Class Calculator
  Public Sub Calc()
    Var i As Integer
  End Sub

End Class</code></pre>



<p>Go ahead and copy the DataPoint class from the top and trying pasting it into a project.</p>



<p>And yes, you can also have multiple classes in the selected text:</p>



<pre class="wp-block-code"><code>Class Test
  Public Sub Hello()
    MessageBox("Hello")
  End Sub

End Class

Class Foo
  Public Sub Bar()
    Var i As Integer
  End Sub

End Class</code></pre>



<p>If you paste in a block of text that is not recognized as Xojo code, it is inserted into a new Note, which is a quick way to get some docs added to your classes.</p>



<p>This pasting of project items works for classes, interfaces and non-nested modules. Now when an LLM creates a class for you, you can easily select the entire thing and paste it to add it to your Xojo project!</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>DesktopHTMLViewer Adds WebView2 Support on Windows</title>
		<link>https://blog.xojo.com/2026/07/08/desktophtmlviewer-adds-webview2-support-on-windows/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 13:46:00 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[2026r2]]></category>
		<category><![CDATA[CEF]]></category>
		<category><![CDATA[DesktopHTMLViewer]]></category>
		<category><![CDATA[WebView2]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16355</guid>

					<description><![CDATA[In Xojo 2026r2, developers targeting Windows now have a new option for&#160;DesktopHTMLViewer: support for Microsoft Edge WebView2. This is an important change for those who&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In Xojo 2026r2, developers targeting Windows now have a new option for&nbsp;DesktopHTMLViewer: support for Microsoft Edge WebView2.</p>



<p>This is an important change for those who want modern web rendering on Windows without the large deployment footprint required by the Chromium Embedded Framework (CEF).</p>



<h2 class="wp-block-heading">Why WebView2 Matters</h2>



<p>Until now, Windows HTML rendering in&nbsp;DesktopHTMLViewer&nbsp;has primarily relied on CEF. While CEF provides excellent compatibility and a consistent Chromium-based rendering engine, it also comes with a substantial deployment cost. Including the required CEF runtime files can add well over 200 MB to an application&#8217;s distribution size.</p>



<p>Using CEF also means applications are tied to specific Chromium and CEF versions bundled with the app itself. Keeping current requires continuously rebuilding and redistributing newer CEF releases as Chromium evolves and security updates are released.</p>



<p>WebView2 changes that equation considerably.</p>



<p>Because WebView2 uses the Microsoft Edge rendering engine already present on many modern Windows systems, applications can avoid bundling a large embedded Chromium runtime entirely. Security and changes to WebView2 are handled through the operating system via Windows Update, rather than requiring applications to ship and maintain their own browser engine updates.</p>



<h2 class="wp-block-heading">WebView2 Runtime Requirements</h2>



<p>One important consideration is that WebView2 may require the Microsoft Edge WebView2 Runtime to be installed on the target system.</p>



<h3 class="wp-block-heading">Windows 11</h3>



<p>Most Windows 11 systems already include WebView2 as part of the operating system, so no additional installation is usually necessary.</p>



<h3 class="wp-block-heading">Windows 10</h3>



<p>Many Windows 10 systems already have the runtime installed because Microsoft distributes it through Edge and Microsoft 365 updates. However, older or managed systems may still require a separate runtime installation.</p>



<p>Applications that depend on WebView2 should verify runtime availability during installation and, if it is not present, either prompt the user or provide a link to download and install the required runtime.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> You can also check&nbsp;<code>DesktopHTMLViewer.IsAvailable</code>&nbsp;at runtime to determine whether WebView2 is available.</p>
</blockquote>



<p>Microsoft provides the runtime here:<br><a href="https://developer.microsoft.com/en-us/microsoft-edge/webview2/" target="_blank" rel="noreferrer noopener">https://developer.microsoft.com/en-us/microsoft-edge/webview2/</a></p>



<h2 class="wp-block-heading">WinUI Targets Use WebView2 by Default</h2>



<p>For WinUI desktop targets, WebView2 is now the default (and only) HTML rendering engine for the DesktopHTMLViewer. In addition, any new projects created in Xojo 2026r2 or later will default to using the WebView2 engine whenever a&nbsp;DesktopHTMLViewer&nbsp;is added to the layout.</p>



<h3 class="wp-block-heading">Enabling WebView2 in older projects or non-WinUI Windows targets</h3>



<p>For traditional Windows desktop targets that are not using WinUI, you can still opt into WebView2 support by enabling the <strong>HTMLViewer uses WebView2</strong> option in the Advanced Windows build setting in the IDE:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="692" src="https://blog.xojo.com/wp-content/uploads/2026/06/HTMLViewerUsersWebView2-1024x692.png" alt="" class="wp-image-16364" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/HTMLViewerUsersWebView2-1024x692.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/06/HTMLViewerUsersWebView2-300x203.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/HTMLViewerUsersWebView2-768x519.png 768w, https://blog.xojo.com/wp-content/uploads/2026/06/HTMLViewerUsersWebView2.png 1504w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>When enabled,&nbsp;DesktopHTMLViewer&nbsp;will use WebView2 instead of CEF for HTML rendering.</p>



<p>This gives you the flexibility to choose between:</p>



<ul class="wp-block-list">
<li>smaller deployment size with WebView2, or</li>



<li>fully self-contained deployment with CEF</li>
</ul>



<p>depending on the needs of your application and target audience. However, moving forward we will be transitioning away from CEF entirely, and it is likely that we will no longer support or update our CEF based HTMLViewer in future releases.</p>



<h2 class="wp-block-heading">Differences from CEF</h2>



<p>Although both CEF and WebView2 are Chromium-based technologies, there are some behavioral differences you should be aware of:</p>



<ul class="wp-block-list">
<li>You may notice some subtle differences in how WebView2 returns results for JSON.Stringify when executed using ExecuteJavaScriptSync. i.e. the result coming back may be quoted.</li>



<li>executeInXojoSync is supported, but it uses JavaScript Promises to simulate synchronous behavior, so existing code may need to be updated to use async/await. Example:&nbsp;<code>const result = await executeInXojoSync("addNumbers", 2, 3);</code></li>



<li>A WebView2-specific cache folder is created alongside the executable. If that directory is not writable, the cache folder is instead created in the user&#8217;s local AppData directory.</li>
</ul>



<h2 class="wp-block-heading">Final Thoughts</h2>



<p>The addition of WebView2 support for&nbsp;DesktopHTMLViewer&nbsp;is a major improvement for Windows desktop deployment in Xojo, and reducing runtime size by hundreds of megabytes while still delivering modern Chromium-based rendering is a significant win.</p>



<p>Those who require rendering consistency or offline/self-contained deployments may still prefer CEF, but WebView2 offers an excellent modern alternative that better matches the direction of the Windows platform itself.</p>



<p>For now, you can choose between either engine depending on your needs, but moving forward we believe WebView2 is the preferred path on Windows. Happy browsing!</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>iOS Framework Improvements</title>
		<link>https://blog.xojo.com/2026/07/08/ios-framework-improvements/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 13:46:00 +0000</pubDate>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[2026r2]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16304</guid>

					<description><![CDATA[The iOS Framework has received a number of additions and improvements in Xojo 2026r2. Some of them will be mandatory for your existing iOS apps&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The iOS Framework has received a number of additions and improvements in Xojo 2026r2. Some of them will be mandatory for your existing iOS apps created with Xojo, while others are targeted to improve your iOS apps&#8217; UI designs and functionality. Let&#8217;s talk about them!</p>



<span id="more-16304"></span>



<h2 class="wp-block-heading">Behind the Scenes…</h2>



<p>Let&#8217;s start with a non-visible change, but a major and important one. In fact, this responds to one of Apple&#8217;s requirements for iOS apps:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>&#8220;In the next major release following iOS 26, UIScene lifecycle will be required when building with the latest SDK; otherwise, your app won’t launch.&#8221;</p>
</blockquote>



<p>Xojo has made the necessary underlying changes in the iOS Framework, and starting with Xojo 2026r2, all iOS apps are compiled/built so they can be run and published meeting this requirement.</p>



<p>What does this mean for you in practice? For any existing Xojo iOS projects, all you need to do is rebuild them with the current version of Xojo. This guarantees that the apps implement the required UIScene lifecycle and can be run without issues both on the iOS simulators and real iOS devices using iOS 26+.</p>



<h2 class="wp-block-heading">MobilePopupMenu Arrives to iOS</h2>



<p>Until now, making simple selections in iOS projects required a complex UI design involving navigation to different screens, the use of tables, containers, etc.&nbsp;Starting with Xojo 2026r2, we have simplified everything with the new MobilePopupMenu control.</p>



<figure class="wp-block-video"><video autoplay controls src="https://blog.xojo.com/wp-content/uploads/2026/06/Simulator-Screen-Recording-iPhone-17-2026-06-08-at-10.29.10.mp4"></video></figure>



<p>In fact, the feature also uses a newly added class for the displayed menu entries: MobileMenuItem (more on this a bit later). It is also possible to add new entries to the menu as text, if you prefer. No matter how entries are added to the PopupMenuControl&#8217;s menu, the underlying items are MobileMenuItem instances, and these are the ones received in the SelectionChanged event handler.</p>



<p>You can populate the MobilePopupMenu entries at design time via the associated Inspector Panel, and select the default SelectedRowIndex value. Of course, you can do the same at runtime and change the control&#8217;s menu entries as you would with the equivalent control on Desktop.</p>



<h2 class="wp-block-heading">MobileMenuItem</h2>



<p>This new class added to the iOS Framework lets you create menu entries for the MobilePopupMenu, as well as for the newly added Menu properties on MobileButton and MobileToolbarButton.</p>



<p>Like its Desktop counterpart, it is possible to create hierarchical menu entries and assign icons to each item. What is specific to MobileMenuItem on iOS are the Destructive (Boolean) and DisplayMode (Enum) properties. When a MobileMenuItem instance is set to Destructive, it will be displayed as such under the iOS Design Guidelines, giving users a clear visual clue about the potentially destructive action.</p>



<p>The DisplayMode property can be set as Regular (the usual dropdown displaying of a menu) or as Palette. With Palette, child entries are presented in a smaller palette with horizontal navigation, which is especially recommended for tight UI designs where options are shown as icons.</p>



<p>If a MobileMenuItem is set to a MobilePopupMenu, it will not display the icons for the menu entries and will discard any  child hierarchies (submenus), as is also the case for DesktopPopupMenu and WebPopupMenu. On the other hand, MobileButton and MobileToolbarButton are able to support submenus and will display the associated icons for every menu entry.</p>



<h2 class="wp-block-heading">MobileButton</h2>



<p>As previously noted, this control has new properties related to displaying a menu. It is possible to set the menu (MobileMenuItem instance) at runtime, and the behavior is controlled by the DisplayMenuAsAction (Boolean) property.</p>



<figure class="wp-block-video"><video autoplay controls src="https://blog.xojo.com/wp-content/uploads/2026/06/Screen-Recording-2026-06-08-at-10.40.58.mp4"></video></figure>



<p>When DisplayMenuAsAction is set to False (the default), the Button fires its Pressed event as usual, and the menu is displayed only after a long press on the button. The menu selection made by the user will be received through the new MenuItemSelected(menu As MobileMenuItem) event handler that can be implemented on the button instance itself. All in all, this provides a good way for the button to react to two different user interactions.</p>



<p>If the DisplayMenuAsAction property is set to True, the associated menu is presented when the button is pressed. In this case, the Pressed event handler will not fire, only its MenuItemSelected (menu as MobileMenuItem) handler will fire after the user makes a selection in the menu.</p>



<h2 class="wp-block-heading">MobileToolbarButton</h2>



<p>MobileToolbarButton also has the new Menu and DisplayMenuAsAction properties, and these behave in the same way as described above. The main difference is that, in this case, the MenuItemSelected event handler needs to be implemented in the containing Screen instance for the NavigationBar to which the MobileToolbarButton has been added, just as the pre-existing ToolbarButtonPressed event handler was.</p>



<figure class="wp-block-video"><video autoplay controls preload="auto" src="https://blog.xojo.com/wp-content/uploads/2026/06/Screen-Recording-2026-06-08-at-10.52.00.mp4"></video></figure>



<h3 class="wp-block-heading">Badges</h3>



<p>In addition to the support of menus, MobileToolbarButton also got the ability to display badges. This is useful in order to simplify many mobile apps UI designs.</p>



<figure class="wp-block-video"><video autoplay controls src="https://blog.xojo.com/wp-content/uploads/2026/06/Screen-Recording-2026-06-08-at-10.57.49.mp4"></video></figure>



<p>The information shown in the badge is set through the MobileToolbarButton.BadgeText property. If this property is set to  an empty string, the badge will not be displayed. In addition, there are other properties you can use to customize the badge&#8217;s appearance:</p>



<ul class="wp-block-list">
<li><strong>BadgeColor As ColorGroup</strong>. Set the background color for the badge.</li>



<li><strong>BadgeTextColor As ColorGroup</strong>. Set the color for the text displayed in the badge.</li>



<li><strong>BadgeTextFont As Font</strong>. Set the font, style and font size to be used by the text in the badge.</li>
</ul>



<h2 class="wp-block-heading">In Summary</h2>



<p>The new iOS Scenes based lifecycle will keep your apps in compliance with the requirement from Apple for future iOS releases beyond iOS 26, and we hope you will find the new menu items useful additions to simplify your iOS UI designs.</p>



<p>We are interested to know more about how you use these features, and invite you to share your iOS stuff on the <a href="https://forum.xojo.com/c/targets/ios/37">Xojo Forum</a> iOS channel!</p>



<p>Special thanks to Xojo MVP Jérèmie Leroy, he is always pushing and helping improve Xojo&#8217;s iOS support. </p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/06/Simulator-Screen-Recording-iPhone-17-2026-06-08-at-10.29.10.mp4" length="150151" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/06/Screen-Recording-2026-06-08-at-10.40.58.mp4" length="406127" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/06/Screen-Recording-2026-06-08-at-10.52.00.mp4" length="327878" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/06/Screen-Recording-2026-06-08-at-10.57.49.mp4" length="76573" type="video/mp4" />

			</item>
		<item>
		<title>New DesktopToolbar Enhancements</title>
		<link>https://blog.xojo.com/2026/07/08/new-desktoptoolbar-enhancements/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 13:45:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[2026r2]]></category>
		<category><![CDATA[DesktopToolbar]]></category>
		<category><![CDATA[Symbols]]></category>
		<category><![CDATA[Toolbar]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16368</guid>

					<description><![CDATA[The latest updates to DesktopToolbar add new options that make toolbars easier to customize across all platforms, along with support for WinUI on Windows. These&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The latest updates to DesktopToolbar add new options that make toolbars easier to customize across all platforms, along with support for WinUI on Windows.</p>



<p>These changes focus on two main areas:</p>



<ul class="wp-block-list">
<li>Expanded button symbol support in&nbsp;DesktopToolbarButton</li>



<li>New layout and presentation control via toolbar style options</li>
</ul>



<h2 class="wp-block-heading">Smarter Icon Handling with Symbols</h2>



<p>A key addition is the new <code>Symbol</code> property on DesktopToolbarButton. It lets you provide a single string containing multiple symbol names separated by semicolons. Each platform will then check that list and use the first symbol it recognizes.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> The Symbol feature is only supported on Windows when using the WinUI target.</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> AllowMulticolorSymbol was added for macOS. When enabled, the OS may render toolbar symbols using multicolor variants where available, instead of enforcing monochrome styling.</p>
</blockquote>



<h3 class="wp-block-heading">Example</h3>



<pre class="wp-block-code"><code>home.Symbol = "house.fill;home;go-home"
home.AllowMulticolorSymbol = True
back.Symbol = "chevron.left;back;go-previous"
forward.Symbol = "chevron.right;forward;go-forward"
search.Symbol = "magnifyingglass;find;system-search"</code></pre>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%"><div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="684" height="542" src="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarMacOS.png" alt="" class="wp-image-16372" style="aspect-ratio:1.2620603364382037;object-fit:cover" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarMacOS.png 684w, https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarMacOS-300x238.png 300w" sizes="auto, (max-width: 684px) 100vw, 684px" /></figure>
</div></div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%"><div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="822" height="394" src="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarLinux2-1.png" alt="" class="wp-image-16378" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarLinux2-1.png 822w, https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarLinux2-1-300x144.png 300w, https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarLinux2-1-768x368.png 768w" sizes="auto, (max-width: 822px) 100vw, 822px" /></figure>
</div></div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"><div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="589" height="296" src="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarWindows.png" alt="" class="wp-image-16374" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarWindows.png 589w, https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarWindows-300x151.png 300w" sizes="auto, (max-width: 589px) 100vw, 589px" /></figure>
</div></div>
</div>



<h3 class="wp-block-heading">How it works</h3>



<p>Instead of relying only on a static icon, the toolbar now attempts to resolve a&nbsp;<em>symbol first</em>. If a symbol is found, it is used in preference to any icon.</p>



<p>The lookup order is:</p>



<ol class="wp-block-list">
<li>First matching symbol in the list</li>



<li>If none resolve, fallback to the standard icon (if one is set)</li>
</ol>



<p>This allows you to provide multiple symbolic names as a fallback chain, improving cross-theme and cross-platform reliability.</p>



<h3 class="wp-block-heading">Where to find the list of supported symbols</h3>



<p>WinUI:&nbsp;<a href="https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.symbol" rel="noreferrer noopener" target="_blank">https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.symbol</a></p>



<p>Linux:&nbsp;<a href="https://specifications.freedesktop.org/icon-naming" rel="noreferrer noopener" target="_blank">https://specifications.freedesktop.org/icon-naming</a></p>



<p>macOS:&nbsp;<a href="https://developer.apple.com/design/human-interface-guidelines/sf-symbols" rel="noreferrer noopener" target="_blank">https://developer.apple.com/design/human-interface-guidelines/sf-symbols</a></p>



<h2 class="wp-block-heading">Better Control Over Toolbar Layout</h2>



<p>The toolbar itself now supports a new&nbsp;<code>Style</code>&nbsp;property.  This controls how buttons are visually arranged.</p>



<p><strong>DesktopToolbarStyles options</strong>:</p>



<ul class="wp-block-list">
<li><strong>Default</strong>
<ul class="wp-block-list">
<li>Generally icon/symbol on top, caption below</li>



<li>On Linux and WinUI: icon/symbol on left, caption on right</li>
</ul>
</li>



<li><strong>IconCaptionVertical</strong>
<ul class="wp-block-list">
<li>Forces vertical layout (icon/symbol above text)</li>
</ul>
</li>



<li><strong>IconCaptionHorizontal</strong>
<ul class="wp-block-list">
<li>Forces horizontal layout (icon/symbol beside text)</li>



<li>Only supported on Linux and Windows</li>
</ul>
</li>



<li><strong>IconOnly</strong>
<ul class="wp-block-list">
<li>Displays only the icon/symbol</li>
</ul>
</li>



<li><strong>CaptionOnly</strong>
<ul class="wp-block-list">
<li>Displays only text labels</li>
</ul>
</li>
</ul>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="676" height="524" src="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarMacOS_IconOnly.png" alt="" class="wp-image-16385" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarMacOS_IconOnly.png 676w, https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarMacOS_IconOnly-300x233.png 300w" sizes="auto, (max-width: 676px) 100vw, 676px" /></figure>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="530" height="378" src="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarLinux_IconOnly.png" alt="" class="wp-image-16386" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarLinux_IconOnly.png 530w, https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarLinux_IconOnly-300x214.png 300w" sizes="auto, (max-width: 530px) 100vw, 530px" /></figure>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="445" height="258" src="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarWindows_IconOnly.png" alt="" class="wp-image-16387" srcset="https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarWindows_IconOnly.png 445w, https://blog.xojo.com/wp-content/uploads/2026/06/ToolbarWindows_IconOnly-300x174.png 300w" sizes="auto, (max-width: 445px) 100vw, 445px" /></figure>
</div>
</div>



<h2 class="wp-block-heading">In Conclusion</h2>



<p>With support for symbols, additional layout styles, and WinUI support on Windows, we&#8217;re making it easier to create toolbars that look more modern, feel more native on each operating system, and adapt better to different user environments. Whether you prefer icon-only toolbars, text labels, or platform-specific symbols, the new options give you more ways to fine-tune the experience for your users without adding extra complexity to your projects.</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Polishing Jade: Now with OpenAI GPT, Local Models and Project Context</title>
		<link>https://blog.xojo.com/2026/07/08/polishing-jade-now-with-openai-gpt-local-models-and-project-context/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 08 Jul 2026 13:45:00 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[2026r2]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Code Generation]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Jade]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16284</guid>

					<description><![CDATA[Jade, the Xojo AI assistant, has several significant improvements in 2026r2 that make it even more useful. Settings Let&#8217;s start with the Settings window, which&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Jade, the Xojo AI assistant, has several significant improvements in 2026r2 that make it even more useful.</p>



<h2 class="wp-block-heading">Settings</h2>



<p>Let&#8217;s start with the Settings window, which now has its own AI panel for adjusting how Jade works.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="855" src="https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.15.42@2x-1024x855.png" alt="" class="wp-image-16287" style="aspect-ratio:1.1976684732590244;width:668px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.15.42@2x-1024x855.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.15.42@2x-300x251.png 300w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.15.42@2x-768x641.png 768w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.15.42@2x-1536x1283.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.15.42@2x.png 1784w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>By default, &#8220;Enable AI Features&#8221; is checked. However, if you are not onboard the AI train, then you can uncheck that setting to turn off Xojo AI integration. This removes the Jade button from the toolbar and also disables the Help menu option.</p>



<p>With AI Features enabled, you can choose the Service to use. By default, &#8220;Anthropic Claude&#8221; is selected so that your previous Jade configuration works the same as before, but you now also have all these services to choose from:</p>



<ul class="wp-block-list">
<li>Anthropic Claude</li>



<li>OpenAI GPT</li>



<li>OpenRouter (Anthropic)</li>



<li>OpenRouter (OpenAI)</li>



<li>Local</li>
</ul>



<p>More information about each of these is in the next section.</p>



<p>The &#8220;Allow access to project context&#8221; option lets Jade ask for information about your project, such as the names of project items, their source code and any compile errors.</p>



<p>The &#8220;Restore conversation from last time&#8221; option indicates if your last Jade conversation will be restored to the chat window when the IDE restarts.</p>



<p>Below this are the text areas where you can enter API keys for the services you are using.</p>



<h2 class="wp-block-heading">Services</h2>



<h3 class="wp-block-heading">Anthropic Claude</h3>



<p>When Anthropic Claud is selected, Xojo uses the most recent version of the Claude Sonnet model, which is currently 4.6. To use this service, you will need to <a href="https://console.anthropic.com/settings/keys">create an Anthropic account</a>, generate an API key and add some credits.</p>



<p>Access to project context is supported with Anthropic Claude.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="447" src="https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.42.32@2x-1024x447.png" alt="" class="wp-image-16293" srcset="https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.42.32@2x-1024x447.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.42.32@2x-300x131.png 300w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.42.32@2x-768x335.png 768w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.42.32@2x-1536x670.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/05/CleanShot-2026-05-14-at-15.42.32@2x-2048x893.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">OpenAI GPT</h3>



<p>When choose OpenAI, Xojo uses a recent version of the gpt-mini model, currently gpt-5.4-mini. This particular model is fast, relatively inexpensive and well suited for coding purposes. To use OpenAI, you will need to <a href="https://platform.openai.com/api-keys">create an OpenAI account</a> , generate an API key and add some credits. There is also an option to earn some free credits that you can optionally turn on.</p>



<p>Access to project context is supported with OpenAI.</p>



<h3 class="wp-block-heading">OpenRouter</h3>



<p><br>OpenRouter is a unified API service that gives access to hundreds of LLMs from different providers (OpenAI, Anthropic, Google, Meta, etc.) through a single endpoint and key.&#8221; Like the others you will first need to create an account, generate an API key and <a href="https://openrouter.ai/workspaces/default/keys">purchase credits</a>. OpenRouter applies these credits as appropriate when using the models you have configured.</p>



<p>There are two options for OpenRouter, so that you can tell it whether to use the Anthropic or OpenAI API. When you choose Anthropic, OpenRouter will automatically route you to Claude models. When you choose OpenAI, OpenRouter will direct you to the default model specified in your OpenRouter account settings.</p>



<p>Not all models will work with Jade and some models have limitations. Currently, only OpenRouter with OpenAI and an OpenAI GPT model supports project context. If you want to try other models, you will likely need to disable the &#8220;Allow access to project context&#8221; setting in Xojo.</p>



<h3 class="wp-block-heading">Local LLM</h3>



<p>A local LLM is a model that you are running locally on your computer or server you control. To run a local LLM, we recommend using <a href="https://lmstudio.ai">LM Studio</a> which makes it easy to download and run models on a local server.</p>



<p>When this is selected, you also need to provide the base URL for your server. With LM Studio, it is typically:</p>



<pre class="wp-block-code"><code>http:&#47;&#47;127.0.0.1:1234</code></pre>



<p>In our testing with Xojo we&#8217;ve found that a Qwen model, such as qwen3-coder-30b works OK. Other models may not provide useful responses or even work at all. Even though this model works, it is far less capable than Anthropic Claude or OpenAI GPT.</p>



<p>If you want to use Ollama, you&#8217;ll have to specify the model name as part of the base URL like this:</p>



<pre class="wp-block-code"><code>http:&#47;&#47;127.0.0.1:11434#qwen2.5-coder:14b</code></pre>



<p>A local LLM does not have access to project context and choosing this service option currently ignores that setting.</p>



<h2 class="wp-block-heading">Which Should You Use?</h2>



<p>Based on our internal testing, Anthropic Claude has the most accurate responses. It is also the slowest and most expensive.</p>



<p>OpenAI with GPT is the fastest and is relatively inexpensive for what you get.</p>



<p>OpenRouter is really only recommended for advanced users, but it does provide an easy way to switch to specific models.</p>



<p>A local LLM is free to use and completely private, but it is also much slower and far less accurate. Depending on the model you choose, a local LLM also requires significant computing resources (RAM and GPU).</p>



<p>I hope you find these Jade improvements useful to you!</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Build a Threaded Find in Files Solution</title>
		<link>https://blog.xojo.com/2026/06/25/build-a-threaded-find-in-files-solution/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Thu, 25 Jun 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Files]]></category>
		<category><![CDATA[Preemptive Threads]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[Threads]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16269</guid>

					<description><![CDATA[In our previous posts, we built a utility to find text inside files within a single folder, and then added recursion to crawl subfolders. But if you&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In our previous posts, we built a utility to <a href="https://blog.xojo.com/2026/04/02/build-a-simple-find-in-files-function/" target="_blank" rel="noreferrer noopener">find text inside files within a single folder</a>, and then <a href="https://blog.xojo.com/2026/05/04/build-a-recursive-find-in-files-function/" target="_blank" rel="noreferrer noopener">added recursion to crawl subfolders</a>. But if you ran that code on a large directory, like your entire Documents folder, you probably noticed two big problems:</p>



<ol class="wp-block-list">
<li>The UI froze completely until the search finished.</li>



<li>If the folder tree was deep enough, you might have hit a&nbsp;<code>StackOverflowException</code>.</li>



<li>We haven&#8217;t actually built a proper UI for it yet!</li>
</ol>



<p>Today, we&#8217;re fixing all three. We&#8217;ll introduce a custom app UI, create a&nbsp;<code>Thread</code>&nbsp;subclass to perform the search in the background, and swap our recursive folder crawl for a flatter, iterative approach to spare our stack memory. We&#8217;ll also add a file size limit to avoid choking on massive unreadable files.</p>



<h2 class="wp-block-heading" id="step-1-designing-the-ui">Step 1: Designing the UI</h2>



<p>First, let&#8217;s build the interface so you have a real application to run. On your main&nbsp;<code>Window1</code>&nbsp;(or whichever Window you are using), we need to add a few controls:</p>



<ul class="wp-block-list">
<li><strong>Path Selection</strong>: Add a&nbsp;<code>DesktopTextField</code>&nbsp;(named&nbsp;<code>fieldPath</code>, set to ReadOnly) to display the chosen folder path, and a&nbsp;<code>DesktopButton</code>&nbsp;(named&nbsp;<code>buttonSelectPath</code>, caption&nbsp;<code>...</code>) next to it to open a&nbsp;<code>SelectFolderDialog</code>.</li>



<li><strong>Search Input</strong>: Add a&nbsp;<code>DesktopSearchField</code>&nbsp;(named&nbsp;<code>fieldSearchTerm</code>) where the user types the text they want to find.</li>



<li><strong>Action Button</strong>: Add a&nbsp;<code>DesktopButton</code>&nbsp;(named&nbsp;<code>buttonSearchThreaded</code>, caption&nbsp;<code>Search Threaded</code>) to start and cancel the search.</li>



<li><strong>Results List</strong>: Add a&nbsp;<code>DesktopListBox</code>&nbsp;(named&nbsp;<code>listResults</code>) and set its Column Count to 3. (Optional: Set the InitialValue of the Column headers to&nbsp;<code>File | Line No. | Context</code>).</li>



<li><strong>Status labels</strong>: Add a&nbsp;<code>DesktopLabel</code>&nbsp;(named&nbsp;<code>labelStatusValue</code>) at the bottom of the window to display the live search progress.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="602" height="452" src="https://blog.xojo.com/wp-content/uploads/2026/05/threaded-find-in-files-xojo-solution.png" alt="" class="wp-image-16272" srcset="https://blog.xojo.com/wp-content/uploads/2026/05/threaded-find-in-files-xojo-solution.png 602w, https://blog.xojo.com/wp-content/uploads/2026/05/threaded-find-in-files-xojo-solution-300x225.png 300w" sizes="auto, (max-width: 602px) 100vw, 602px" /></figure>
</div>


<h2 class="wp-block-heading" id="step-2-creating-the-thread-subclass">Step 2: Creating the Thread Subclass</h2>



<p>Threading lets us run our file search simultaneously with the main application, keeping our UI totally responsive.</p>



<p>Instead of writing standard methods, we need to create a dedicated Class.</p>



<ol class="wp-block-list">
<li>Add a&nbsp;<strong>New Class</strong>, in the <code>SearchUtils</code> module and name it&nbsp;<code>FileSearch</code>.</li>



<li>In the Inspector, change its&nbsp;<strong>Super</strong>&nbsp;to&nbsp;<code>Thread</code>.</li>



<li>Add the following Properties to your new class:
<ul class="wp-block-list">
<li><code>MaximumFileSizeMB As Integer = 1</code></li>



<li><code>SearchTerm As String</code></li>



<li><code>TargetFolder As FolderItem</code></li>



<li><code>startTime As Double</code>&nbsp;(Set Scope to Private)</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading" id="defining-custom-events">Defining Custom Events</h3>



<p>We need our Thread to broadcast events to the Window that&#8217;s holding it. Add these three Event Definitions to your&nbsp;<code>FileSearch</code>&nbsp;class:</p>



<ul class="wp-block-list">
<li><code>Complete(timeElapsed as Double)</code></li>



<li><code>MatchFound(result as SearchUtils.SearchHit)</code></li>



<li><code>StatusUpdate(currentPath as String)</code></li>
</ul>



<h2 class="wp-block-heading" id="step-3-the-iterative-approach-no-recursion">Step 3: The iterative approach</h2>



<p>Recursion is elegant, but crawling a hierarchy thousands of folders deep throws a&nbsp;<code>StackOverflowException</code>. Instead, we flatten the traversal using an array as a queue. We start by adding our root folder&#8217;s children to an array. As we iterate through that array, any folders we find get their children appended to the&nbsp;<em>end</em>&nbsp;of the same array.</p>



<p>Here is exactly how it looks in the Thread&#8217;s&nbsp;<code>Run</code>&nbsp;event. Add the&nbsp;<code>Run</code>&nbsp;event to your&nbsp;<code>FileSearch</code>&nbsp;class and use this exact code and notice the use of&nbsp;<code>AddUserInterfaceUpdate</code>&nbsp;to safely queue UI updates:</p>



<pre class="wp-block-code"><code>Sub Run() Handles Run
  Var maxFileSize As Double = If( Self.MaximumFileSizeMB &lt; 1, 999999999 * 1024 * 1024, Self.MaximumFileSizeMB * 1024 * 1024 )
  
  Var result As Dictionary
  
  Var lastUpdate As Integer = System.Microseconds
  
  If Not (targetFolder Is Nil) And targetFolder.Exists And Not searchTerm.IsEmpty Then
    
    Var child As FolderItem
    Var toSearch() As FolderItem
    For Each child In targetFolder.Children
      toSearch.Add( child )
    Next
    
    Var ti As TextInputStream
    Var line As String
    Var lineNumber As Integer = -1
    
    For index As Integer = 0 To toSearch.LastIndex
      child = toSearch(index)
      
      If System.Microseconds - lastUpdate &gt; 1000000 Then
        result = New Dictionary
        result.Value( "type" ) = "status"
        result.Value( "current" ) = child.NativePath
        AddUserInterfaceUpdate( result )
        lastUpdate = System.Microseconds
      End If
      
      If child.IsFolder Then
        Try
          
          #Pragma BreakOnExceptions False
          
          For Each innerChild As FolderItem In child.Children
            toSearch.Add( innerChild )
          Next
          
          #Pragma BreakOnExceptions Default
          
        Catch e As IOException
          '// Skip inaccessible folders
        End Try
      Else
        If child.Length &lt; maxFileSize Then
          Try
            ti = TextInputStream.Open( child )
            ti.Encoding = Encodings.UTF8
            
            lineNumber = 0
            
            While Not ti.EndOfFile
              lineNumber = lineNumber + 1
              line = ti.ReadLine
              If line.Contains( searchTerm, ComparisonOptions.CaseInsensitive ) Then
                result = New Dictionary
                result.Value( "type" ) = "match"
                result.Value( "path" ) = child.NativePath
                result.Value( "lineNo" ) = lineNumber
                result.Value( "lineText" ) = line
                AddUserInterfaceUpdate( result )
              End If
            Wend
          Catch ioe As IOException
            '// Skip unreadable files
          End Try
        End If
      End If
    Next
  End If
  
  result = New Dictionary( New Pair( "type", "complete" ) )
  AddUserInterfaceUpdate( result )
End Sub</code></pre>



<h2 class="wp-block-heading" id="step-4-feeding-updates-to-the-ui-safely">Step 4: Sending Updates to the UI safely</h2>



<p>In a thread, you&nbsp;<strong>cannot</strong>&nbsp;update UI controls directly. That&#8217;s why we used&nbsp;<code>AddUserInterfaceUpdate</code>&nbsp;above passing a&nbsp;<code>Dictionary</code>&nbsp;of data. This triggers the Thread&#8217;s&nbsp;<code>UserInterfaceUpdate</code>&nbsp;event on the main UI thread.</p>



<p>Add the&nbsp;<code>UserInterfaceUpdate</code>&nbsp;event to your&nbsp;<code>FileSearch</code>&nbsp;class:</p>



<pre class="wp-block-code"><code>Sub UserInterfaceUpdate(data() As Dictionary) Handles UserInterfaceUpdate
  For Each d As Dictionary In data
    Select Case d.Value( "type" )
    Case "match" 
      Var hit As New SearchHit( d.Value( "path" ), d.Value( "lineNo" ), d.Value( "lineText" ) )
      RaiseEvent MatchFound( hit )
    Case "complete"
      RaiseEvent Complete( (System.Microseconds - startTime) / 1000 )
    Case "status"
      RaiseEvent StatusUpdate( d.Value( "current" ) )
    End Select
  Next
End Sub</code></pre>



<p>And finally, add a public method called&nbsp;<code>Search</code>&nbsp;to the class, making sure it executes Preemptively across CPU cores:</p>



<pre class="wp-block-code"><code>Public Sub Search(path As FolderItem, term As String)
  Self.Type = Thread.Types.Preemptive
  
  startTime = System.Microseconds
  
  Self.TargetFolder = path
  Self.SearchTerm = term
  Self.Start
End Sub</code></pre>



<h2 class="wp-block-heading" id="step-5-wiring-the-ui">Step 5: Wiring the UI</h2>



<p>Now, let&#8217;s bring it all together. Select&nbsp;<code>Window1</code>&nbsp;and&nbsp;<strong>simply drag the&nbsp;<code>FileSearch</code>&nbsp;class from your Navigator onto your Window.</strong>&nbsp;It will appear in a shelf at the bottom as&nbsp;<code>FileSearch1</code>&nbsp;(rename it to&nbsp;<code>seeker</code>).</p>



<p>Implement the Event Handlers to your new&nbsp;<code>seeker</code>&nbsp;control:</p>



<p><strong>seeker.Complete:</strong></p>



<pre class="wp-block-code"><code>Sub Complete(timeElapsed As Double) Handles Complete
  buttonSelectPath.Enabled = True
  buttonSearchThreaded.Caption = "Search Threaded"
  fieldSearchTerm.Enabled = True

  Var count As Integer = listResults.LastRowIndex + 1
  Var timeElapsedSeconds As Double = timeElapsed / 1000
  labelStatusValue.Text = "Complete in " + timeElapsedSeconds.ToString( "#0.00" ) + " seconds! " + count.ToString( "#" ) + " results found."
End Sub</code></pre>



<p><strong>seeker.MatchFound:</strong></p>



<pre class="wp-block-code"><code>Sub MatchFound(result As SearchUtils.SearchHit) Handles MatchFound
  listResults.AddRow( result.FilePath, result.LineNumber.ToString( "#" ), result.LineText )
  listResults.RowTagAt( listResults.LastAddedRowIndex ) = result
End Sub</code></pre>



<p><strong>seeker.StatusUpdate:</strong></p>



<pre class="wp-block-code"><code>Sub StatusUpdate(currentPath As String) Handles StatusUpdate
  labelStatusValue.Text = "Searching '" + currentPath + "'"
End Sub</code></pre>



<p id="step-5-wiring-the-ui">And finally, the code in&nbsp;<code>buttonSearchThreaded</code>&nbsp;to kick off the search (and handle nice cancellation):</p>



<pre class="wp-block-code"><code>Sub Pressed() Handles Pressed
  Select Case Me.Caption
  Case "Search Threaded"
    If fieldSearchTerm.Text.Length &gt;= 3 Then
      If seeker.ThreadState = Thread.ThreadStates.NotRunning Then

        listResults.RemoveAllRows

        fieldSearchTerm.Enabled = False
        buttonSelectPath.Enabled = False
        labelStatusValue.Text = "Searching..."

        Me.Caption = "Cancel"

        seeker.Search( Self.path, fieldSearchTerm.Text )

      End If
    End If
  Case "Cancel"
    seeker.Stop
    labelStatusValue.Text = "Cancelled"
  End Select
End Sub</code></pre>



<h2 class="wp-block-heading" id="step-5-wiring-the-ui">Summary</h2>



<p id="step-5-wiring-the-ui">By switching from recursion to a linear queue, we bulletproofed the code against&nbsp;<code>StackOverflowExceptions</code>. By moving the heavy lifting to a preemptive&nbsp;<code>Thread</code>, we completely unlocked the UI, making the app feel incredibly fast and responsive even while chewing through thousands of files. And using&nbsp;<code>AddUserInterfaceUpdate</code>, we safely pipe results directly back to the user without locking up the UI!</p>



<p id="step-5-wiring-the-ui">You can download the project here: <a href="https://blog.xojo.com/wp-content/uploads/2026/05/SearchUtils.FindInFiles.zip">SearchUtils.FindInFiles.zip</a></p>



<h3 class="wp-block-heading" id="step-5-wiring-the-ui">Special Thanks</h3>



<p id="step-5-wiring-the-ui">A huge shoutout and special thanks to Xojo MVP and forum user&nbsp;<strong>Anthony G. Cyphers</strong>. Anthony generously provided the solution to evolve the&nbsp;<code>SearchUtils</code>&nbsp;module into this threaded version, along with the demo app UI.</p>



<p id="step-5-wiring-the-ui"><em>P.S. Got your own spin on this utility? Have ideas for new features or alternative approaches? Jump into the&nbsp;</em><a href="https://forum.xojo.com/c/code-sharing/62" data-type="link" data-id="https://forum.xojo.com/c/code-sharing/62" target="_blank" rel="noreferrer noopener">Xojo Code Sharing Forum</a><em>&nbsp; and share your improvements with the community!</em></p>



<p id="step-5-wiring-the-ui">Happy coding!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Spotlight On: OfficeTime</title>
		<link>https://blog.xojo.com/2026/06/09/spotlight-on-officetime/</link>
		
		<dc:creator><![CDATA[Alyssa Foley]]></dc:creator>
		<pubDate>Tue, 09 Jun 2026 17:53:26 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Spotlight On]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=16191</guid>

					<description><![CDATA[Spotlight On posts focus on Xojo community members. We’ll use this space to tell the stories of people using Xojo, share amazing Xojo-made apps and&#8230;]]></description>
										<content:encoded><![CDATA[
<p><em>Spotlight On posts focus on Xojo community members. We’ll use this space to tell the stories of people using Xojo, share amazing Xojo-made apps and spread awareness of community resources. If you have an app, a project or a person you want to see featured in Spotlight On,&nbsp;<a href="mailto:hello@xojo.com" target="_blank" rel="noreferrer noopener">tell us about it</a>!</em></p>



<p>Stephen Dodd has been a Xojo developer since 2001. Over two decades, he’s seen Xojo evolve, and his work embodies the cross‑platform strength Xojo offers users. During his recent Xojo license renewal, he commented &#8220;See the beautiful cross platform app made with it.&#8221; We absolutely love receiving comments like this; they remind us why we do what we do and how our community uses Xojo to create remarkable projects. Immediately I shared Stephen&#8217;s app, <a href="http://www.officetime.net/" target="_blank" rel="noreferrer noopener">OfficeTime</a>, with the team and it didn&#8217;t take long before someone said &#8220;this deserves a Spotlight On!&#8221;. Fortunately, Stephen was kind enough to say yes and answer our questions.</p>



<h3 class="wp-block-heading"><strong>Mac, Windows or Linux?</strong></h3>



<p>Mac + Windows of course. Evaluating Linux demand.</p>



<h3 class="wp-block-heading"><strong>What do you wish more people would ask you about when it comes to your work? Is there an aspect of your work that people often overlook but you wish they were more curious about?</strong></h3>



<p>I&#8217;m passionate about the user experience. The simpler the app, the more time is needed. OfficeTime came about when the staff at the agency I was head of hated tracking their time. Everyday I&#8217;d walk by graffiti someone plastered that said &#8220;Start writing. What&#8217;s stopping you?&#8221; Coding is writing. OfficeTime is successful because I&#8217;m not &#8216;into&#8217; time tracking. I&#8217;m into something that does its job and stays out of your way. </p>



<p>I’m fond of hiding complication until it’s needed. For example, the user can change the rate of an existing category in OfficeTime. That introduces choices for what previously tracked time is affected. We hide all that interface until the user actually starts typing a new rate. Unfortunately for the developer, the simpler you make it, the longer it takes.&nbsp;</p>



<h3 class="wp-block-heading"><strong>What is something that has surprised you about coding in the last 5 years?</strong></h3>



<p>How fricking long implementing full featured, offline first cloud sync takes to get right. Cloud sync is deceptively hard. The majority of our bugs seem to revolve around timing issues of when data / UI is available or not. </p>



<h3 class="wp-block-heading"><strong>Xojo isn’t the only tool in your kit. What is a piece of software more people should know about?</strong></h3>



<ul class="wp-block-list">
<li>OfficeTime to track my time!</li>



<li>TextExpander to hot key in code snippets and customer support replies.</li>



<li>Claude because it just has a more natural, intuitive output than ChatGPT or Gemini.&nbsp;</li>
</ul>



<h3 class="wp-block-heading">Which three Xojo language features or framework capabilities do you find yourself relying/using on the most?</h3>



<p>We hammer that listbox pretty heavily.  It’s core to all the views and reports.</p>



<h3 class="wp-block-heading"><strong>What did you first build with Xojo? And when was that?</strong></h3>



<p>In the 90’s, using Xojo (then called REALbasic), I built a neural network (before AI was cool) to learn to play tic tac toe.</p>



<p>I originally took up Xojo because the O’REILLY book had a cheetah on it which meant it had to be fast. All the Microsoft books had bugs on them. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading"><strong>What do you build with it now?</strong></h3>



<p>OfficeTime is a cross platform app to better track your time so you can bill more or be more accountable for fixed price projects. &nbsp;The Mac/PC side is Xojo with a few custom written controls. It syncs with an iPhone/iPad app that was written in Xcode long before Xojo offered mobile development.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="774" src="https://blog.xojo.com/wp-content/uploads/2026/04/OfficeTime-Projects-with-budget-1024x774.png" alt="" class="wp-image-16212" style="aspect-ratio:1.3236291306902943;width:644px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2026/04/OfficeTime-Projects-with-budget-1024x774.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/04/OfficeTime-Projects-with-budget-300x227.png 300w, https://blog.xojo.com/wp-content/uploads/2026/04/OfficeTime-Projects-with-budget-768x580.png 768w, https://blog.xojo.com/wp-content/uploads/2026/04/OfficeTime-Projects-with-budget.png 1272w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><strong>Do you earn a living with Xojo?</strong></h3>



<p>Yes.</p>



<h3 class="wp-block-heading"><strong>What’s your biggest Xojo success?</strong></h3>



<p>OfficeTime</p>



<h3 class="wp-block-heading">If you were introducing Xojo to a friend, which three words would you use to describe it?</h3>



<p>Easy cross platform</p>



<p><em>Thank you to Stephen Dodd for answering questions and sharing his Xojo experience with the community.&nbsp;If you have an app, a project or a person you want to see featured in Spotlight On,&nbsp;<a href="mailto:hello@xojo.com" target="_blank" rel="noreferrer noopener">tell us about it</a>!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p class="has-text-align-center has-text-color has-link-color wp-elements-a0a2ac26ad214a49dac577734d259176" style="color:#84bd00"><a href="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Download Xojo</a></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
