Updating Records with Transactions

In my last blog post I talked about inserting records into a SQLite database and found that using transactions makes them incredibly fast.  Does the same hold true for updating an existing record?  We’ll find out.

In this set of tests I inserted 100,000 records and then randomly selected 10,000 records to update with our same random name, age, and date values.  In theory this means I have records distributed all over the range of the database.

In the first test we use a simple RecordSet which means we have to query for it first.  Then call its Edit method, change the values and call update.  It’s a two step process.

For i As Integer = 0 To ari.Ubound
   Dim rs As recordset
   rs = db.SQLSelect("Select * from t_table where table_id = " + Str(ari(i)))
   If db.error Then
      If db.Error Then
         MsgBox "DB Error: " + db.ErrorMessage
   rs.Field("Name").stringvalue = GetName
   rs.Field("Age").integervalue = GetAge
   rs.Field("TheDate").DateValue = New date
   If db.Error Then
      MsgBox "DB Error: " + db.ErrorMessage

Unsurprisingly, this method took about 49 seconds for 10,000 records.

In test two I switched to using a PreparedStatement to update the record.

Dim sql As String = "Update t_table Set Name = ?, Age=?, TheDate =? WHERE table_id = ?"
Dim ps As SQLitePreparedStatement = db.Prepare(sql)
ps.BindType(0, SQLitePreparedStatement.SQLITE_TEXT)
ps.BindType(1, SQLitePreparedStatement.SQLITE_INTEGER)
ps.BindType(2, SQLitePreparedStatement.SQLITE_TEXT)
ps.BindType(3, SQLitePreparedStatement.SQLITE_INT64)
For i As Integer = 0 To ari.Ubound
   ps.Bind(0, GetName)
   ps.bind(1, GetAge)
   ps.Bind(2, New Date)
   ps.bind(3, ari(i) )
   If db.Error Then
      MsgBox "DB Error: " + db.ErrorMessage

When run for 10,000 records this takes about 47 seconds so there is a little bit of time savings by not querying the database for the data to begin with.  It’s also possible that the PreparedStatements aren’t nearly as efficient as one would hope.

I then repeated the same tests within a Transaction.  In both cases updating records effectively took no time at all!  If I increase the number of Updates to 10,000 both the RecordSet update and the PreparedStatement takes about 8 seconds.  

I’m surprised at these results because you would think that doing the query required for the RecordSet would take more time but it’s no different than using the PreparedStatement SQL Update.  Why is that?  I have a couple of theories.  First, the table isn’t very complex with only 4 columns and I’m only ever querying and updating based on the primary key.  I’m sure a more complex query would slow things down.  We also have no indexes on any the columns which can cause the database to do more work behind the scenes.

Regardless, we learned a few things today.  First, database transactions are critical to large scale database manipulation in a timely manner.  Second, it doesn’t matter if you use RecordSet Edit/Update or if you use PreparedStatements as either one is fast enough.

What sorts of questions do you have about databases that I can test for you?

Database Transactions in Xojo

Every now and then someone on the Xojo forum wonders why inserting data into an SQLite database is so slow.  Databases are designed to hold billions of records and do it fast, right?  So why is their application so slow?  The answer is they are relying upon the built-in transaction in Xojo.

By default SQLite databases do an automatic transaction for you.  This means that as soon as you attempt to insert, update, or delete data the work to write that change to disk happens as soon as possible.

For example, let’s take the following bit of code to insert data into a table:

For i As Integer = 1 To kMax
   Dim dbr As New DatabaseRecord
   dbr.Column("Name") = GetName
   dbr.IntegerColumn("Age") = GetAge
   dbr.DateColumn("TheDate") = New date
   db.InsertRecord "t_table", dbr
   If db.Error Then
      MsgBox "DB Error: " + db.ErrorMessage

GetName gets a random name from an array that has 26 names in it and adds a random integer between 1000 and 10000.  GetAge returns a random integer between 1 and 74. 

This is pretty simple insert and if you run this 10,000 times it takes roughly 49 seconds saving to a desktop SQLite file on my 5k iMac.  And in so doing the application is locked up for that entire time because I’m in the tight loop.  This is simply unacceptable.

I’m sure someone is screaming why are you using the DatabaseRecord!  It’s slow!  It’s inefficient!  You should be using PreparedStatement’s!  Okay, so using pretty much the same logic:

Dim sql As String = "Insert into t_table (Name, Age, TheDate) Values(?, ?, ?);"
Dim ps As SQLitePreparedStatement = db.Prepare(sql)
ps.BindType(0, SQLitePreparedStatement.SQLITE_TEXT)
ps.BindType(1, SQLitePreparedStatement.SQLITE_INTEGER)
ps.BindType(2, SQLitePreparedStatement.SQLITE_TEXT)
For i As Integer = 1 To kMax
   ps.Bind(0, GetName)
   ps.bind(1, GetAge)
   ps.Bind(2, New Date)
   If db.Error Then
      MsgBox "DB Error: " + db.ErrorMessage

This takes about 48 seconds.  No big time savings there.  Obviously that’s not the improvement we need.

What we need to do is put these inserts in a database transaction using the following bit of code before the loop starts:

If db.Error Then
   MsgBox "DB Error: " + db.ErrorMessage

And then at the end use:


Using the DatabaseRecord method takes a whopping 1 second with 10,000 records.  Using the prepared statement is so fast that my measured elapsed time in seconds is effectively 0.  

If I up the number of records inserted to 1,000,000 I get an interesting result.  The DatabaseRecord method takes 27 seconds where the PreparedStatement method takes 47 seconds.  And if I declare the PreparedStatement inside the loop it now takes 55 seconds.

What have we learned in this blog post?  First, using a database transaction is considerably faster than using the default transaction behavior.  Second, using DatabaseRecord is pretty fast and depending upon the number of record inserted it might be considerably faster.  Honestly, I didn’t expect this.  

In the next blog post I’ll look at Record updates and what are the best methods.

Formatted Text 3.2

Lenexa, KS (February 12th 2019) — BKeeney Software Inc. releases a major update to Formatted Text Control. Developers can now implement tab leaders, change character spacing, implement text drop shadows, and use standard keyboard handling in their applications that require a robust word processing control. This version contains dozens of new, changed, and updated items.

Formatted Text Control (FTC) is a set of classes that offer developers word processing capabilities for their Mac and Windows desktop applications. FTC has several viewing modes that gives users a choice of Page View, Edit View, or Single Line view. FTC supports inline graphics, hyperlinks, and text formatting that the built-in Xojo TextArea control just can’t do. Users can import and save text, RTF, and XML format documents.

FTC version 3.2.0 is a free update to all 3.x users and is recommended. Existing users should be notified via FileShare but can contact BKeeney Software at support@bkeeney.com if they have any questions.

FTC is sold as unencrypted source code and costs $150 USD. More information and demo projects are available at https://www.bkeeney.com/formatted-text-control/ .

Complete change list:
New Items:

  • Contains code from the ImagePlay Effects Library – http://imageplay.sourceforge.net 
  • Tab Leaders implemented
  • Issue #3832: Implement Control + Up/Down Arrow Key Handling
  • Issue #3833: Implement paragraph moving via keyboard handling
  • Issue #3700: Drop Shadow available on Windows and Linux
  • Issue #3795: The FTDocument properties characterStyles and paragraphStyles need to be accessible to subclasses.

Added CharacterStyles and ParagraphStyles getter/setters so developers can create their own style editor.
* Character Spacing implemented (requires Xojo >= 2015.4)

Bug Fixes:

  • Issue #3650: CustomObjects Demo: Added FTFile.Clone method so it works with FTIterator propertly.
  • Issue #3653: macOS: “getDoubleClickTime” – Cocoa replacement for old CarbonLib call
  • Issue #3699: Add Win64 Declares
  • Issue #3654: Hi-DPI Mode: FTPicture – Handles drawn incorrect and matches wrong.
  • Issue #3702: DragRect is half height in HiDPI
  • Fixed an issue with FTParagraph clones that have a different ID after going through the FTIterator
  • Issue #2007/3605: Candidate Window Shows up in Wrong Location
  • Issue #3646: FTParagraph.getXML saves wrong TabStop Properties
  • Issue #3709: FTPicture ignores Nudge property
  • Issue #3748: FTDocument.selectionBold,Italic, shadow, strikethrough, subscript, superscript, underline now works properly
  • Issue #3752: FTRBScript: Fix for printing line numbers
  • Issue #3763: RTFReader/FtcRtfReader ignored the left/right margin and first indent of paragraphs.
  • Issue #3764: RTFReader ignored “\sb” SpaceBefore of paragraphs.
  • Win64 Issue: Modified FTCUndoPaste.constructor and FTCUndoManager.savePaste to allow pasting (Xojo Compiler Issue. Feedback 53967)
  • Issue #3750: Suggestion & comparison of the Office applications for the display optimization of the paragraph background color
  • Issue #3775: Implement Corner Color Property in Formatted Text (Switch between Light/DarkMode – Xojo Version >= 2018.3)
  • Issue #3777: Implement Page Shadow Property in Formatted Text (Switch between Light/DarkMode – Xojo Version >= 2018.3)
  • Issue #3755: Printing has the side-effect of scrolling the editing window to the top
  • Issue #3794: FTDocument.getSelectedParagraphs returns first paragraph of multi-paragraph doc regardless of insertion point
  • Issue #3796: FTStyleRun.copyStyleData does not copy background color
  • Issue #3820: RTFWriter missed “\par” after the last Paragraph
  • Issue #3774: FormattedText — changeParagraphMargins method name changeParagraphMarigns
  • Issue #3762: FTDocument.selectionFontColor returns sameColor false when it should be true
  • Issue #3842: FTStyleRun.updateWith Style sets textColor black when undefined
  • Issue #3806: FTDocument.addParagraphStyle and addCharacterStyle bypassed by insertXML and cannot be overridden in subclass
  • Issue #3818: Print RB Code Editor: Unwanted positive y-offset of the content compared to its line number
  • Issue #3637: FTCParagraphStyle.backgroundColor won’t set correctly
  • Issue #3910: RTF-Reader ignores local value for first line indent in paragraphs
  • Issue #3914: First Paragraph on Page with Background Color ignores Before Space
  • Issue #3917: Paragraphs Background Color ignores Hanging Indent


  • Renamed FormattedText.xDisplayPosition to FormattedText.hScrollValue to better reflect what it is.
  • Renamed FormattedText.lastXDisplayPosition to FormattedText.lastHScrollValue
  • Renamed FormattedText.yDisplayPosition to FormattedText.vScrollValue to better reflect what it is.
  • Renamed FormattedText.lastYDisplayPosition to FormattedText.lastVScrollValue
  • Renamed FormattedText.GetResolution to FormattedText.GetMonitorPixelsPerInch to better reflect what it does.
  • Renamed FTDocument.SetResolution to FTDocument.setMonitorPixelsPerInch
  • Renamed FTDocument.GetResolution to FTDocument.getMonitorPixelsPerInch
  • Renamed FTDocument.Resolution to FTDocument.MonitorPixelsPerInch
  • FormattedText.DISPLAY_ALIGN_CENTER/LEFT/RIGHT replaced with Display_Alignment enum
  • FormattedText.MODE_PAGE/NORMAL/EDIT/Single replaced with Display_Mode enum
  • FTLine.FIRST_LINE/MIDDLE/LAST/BOTH replaced with Line_Type enum
  • FTPicture.Handle constants converted to FTPicture.Handle_Type enum
  • FTParagraph.Alignment constants converted to FTParagraph.Alignment_Type enum
  • Removed Alignment constants from RTFConstants module
  • Changed how hyperlinks are drawn in FTObject.drawHyperLink
  • Changed how the gradient shadow is drawn in FTPage.drawPageViewMode
  • Changed how strikethroughs are drawn in FTObject.drawStrikethrough
  • Changed how underline is drawing in FTObject.drawUnderline
  • Can now read/write shadow properties from/to RTF Documents
  • Added AcceptFileDrop to test window for testing custom objects. Added FTFile into project.
  • Changed how Styles are saved and read in XML format.
  • Issue #3802/1456: Command + (Shift Key) + Arrow Keys doesn’t move insertion point correctly
  • Changed RB Script classes to Xojo Script.
  • Now have TabLeaders (WORK IN PROGRESS)
  • Embedded FTC demo now does text formatting with keyboard shortcuts.
  • Removed unused FTDocument.DocOffset method.
  • Fixed TargetCocoa and TargetWin32 constants with more appropriate ones for 2018 R4.
  • Removed duplicated code line in RTFReader.SetupKnownCommands
  • Updated ParagraphWindow to easy format First Line and Hanging Indents

* Issue #3753: PageBreaks won’t load from RTF

modGtk3 for Xojo

Linux has always been kind of an odd duck when it comes to Xojo.  If you create Linux applications with the IDE running in Linux the default sizes for controls is 26 which is different than MacOS or Windows since their default control height is 22.  See the initial screenshot:  the controls in Linux just don’t look right at the default Mac/Win control height.

The standard answer for many years was to subclass your controls and modify the height of the controls in Linux.  This was okay but it hard to make your UI look good on all three target platforms.

Xojo 2017 R2 changed the drawing system it uses.  The switch to GTK3 made it possible to modify the CSS of your application theoretically making it possible to make all platforms look and behave the same.

Just because you can modify the CSS means it’s a trivial task.  Several long time Xojo community members Jim McKay and Jürg Otter stepped up to the plate and put in the time to figure it out.  The result is at https://bitbucket.org/pidog/modgtk3/src/master/.

In this screenshot you can see that everything looks as you’d expect.

Implementing this in your own project is simple.  Download the BitBucket repository, open the project in Xojo and copy the GTK3 folder into  your own project.  Then in the App.Open event put these three lines in:


That’s it.  Voila!  Now your app looks better in Linux and there’s no need to subclass your controls.  I realize this isn’t magic but it sure seems like it.

BKS Shorts 2.0.9

Today we released BKeeney Shorts 2.0.9.  This is a free update to all version 2.0.x users.  

Shorts is the award winning reporting tool for Xojo applications.  Shorts allows a Xojo developer to embed a report designer inside in a desktop application, view reports in any resolution on desktop or web applications, save report files to file or to a database, and to export reports to HTML, CSV, and PDF (requires the DynaPDF plugin from MBS).  Shorts works with SQLite, CubeSQL, PostgreSQL, MySQL, MS SQL Server, ODBC, and Informix (requires the SQL plugin from MBS).     Shorts comes as 100% unencrypted Xojo source code.    


  • Align: Justify text! (#3627)
  • Report Designer can now copy and paste! (#3691)
  • Method to tell the DynaPDF renderer where to look for custom fonts
  • Report Designer bands with a Band Script now offer an indication in the designer (#3701)
  • Schema Zapper will remove the DB schema from the JSON for manual template changes (#3632)


  • Running in HiDPI in Windows using Xojo 2018 R3 now shows report preview in proper clarity
  • Report Designer no longer nags about deleting items that can be undone
  • Designer window positioning suggested by container event for better scoping
  • Standardized naming on winReportDesigner
  • DesignCanvas.GetUniqueName is now more smart
  • DBWrapper.DatabaseFile is now DBWrapper.SQLiteDatabaseFile for consistency
  • ReportBKS no longer redundantly loads styles to the global styles dictionary
  • PAF_PrintKit.DictStyles is now protected for clarity in code


  • PreviewCC Mojave / 2018R3 & R4 graphical glitch workaround
  • Reports where the page header is empty no longer have multiple page positioning issues
  • Added Numeric and Decimal datatypes for PostgreSQL, maps to Double
  • Views now show up in the Manual Relations editor (#3731)
  • Designer window will no longer reposition if the report template positioning doesn’t fit onscreen (#3651)
  • Fixed localization mismatch in the navigator (#3851)
  • DBWrapper no longer assumes SQLite databases have a database file (#3694)


  • PAFConfirm function, please use the modGlobals.Alert function instead
  • winReportDesigner no longer has a Placard control
  • PAF_DatabaseKit.CreateDatabaseFile function, it served no purpose in the Shorts project

For more pricing, demo versions, and training videos please visit http://www.bkeeney.com/allproducts/bkeeney-shorts/

Nil Recordset

The question on how to deal with nil RecordSets is OFTEN asked in the Xojo forums.  Either the original poster or a well meaning responder will do something like this:

dim rs as recordset 
rs = db.sqlselect(sql)
If rs <> Nil Then
     If Not rs.EOF Then
       // No Records in Table or bad querry?
     End If
End If

It works, but it only masks the real issue.  Why is rs nil in the first place?  The answer is because the SQL statement to get the RecordSet had an error!  What is that error?  We have no idea because the code doesn’t ask for the error.

Most of the time the database will give you an error message that will point you in the right direction.  How do you tell that the database had an error?  You check the Error property.

dim rs as recordset 
rs = db.sqlselect(sql)
if db.error then
     //Do something

The database can give you an error code but this varies from database to database so I don’t find it exceptionally useful.  However, there is an ErrorMessage property that gives you a human readable message.  

dim rs as recordset 
rs = db.sqlselect(sql)
if db.error then
     MsgBox “DB Error: “ + db.ErrorMessage

In this example I’m showing this to the user but this is probably not a great idea for most uses because you don’t want the average user to know what happened.  However, it’s great while debugging.

The error you get back might be a little mysterious.  SQL is a language specific to databases and the error message returned expects you know a little bit about databases.

The second part of my message to you is that if you’re using SQLSelect or SQLExecute in your code you should look at PreparedStatements.  They’re safer in that PreparedStatement have some security features and does the heavy lifting of taking the input data and putting it into the right format.  What do I mean by this?

In a normal SQL statement you would have an SQL statement like this:

dim sql as string
sql = “Select * from users where last_name = ‘Keeney’;”

This selects all users whose last name is ‘Keeney’.  If you were going to allow the user to search for whatever name they want you would end up doing something like this:

dim sName as string
sName = txtSearchField.Text
sql = “Select * from users where last_name = '“ + sName + “’;”

Note that I had to manually put the single quotes in before and after the name since the database column is text.  This works great until you enter an Irish name like O’Neil.  The database will choke on this because it has an extra apostrophe in the statement.  You can escape this data yourself but what a pain.  Instead, use a PreparedStatement.

dim ps as SQLitePreparedStatement
dim sql as string
sql = “Select * from users where last_name = ?”
ps = db.prepare(sql)
ps.bindtype(0, SQLitePreparedStatement.SQLITE_TEXT
ps.bind(0, txtSearch.text)
dim rs as Recordset
rs = ps.SQLSelect
if db.error then
     MsgBox db.errormessage

Nowhere in the code do I have to put in apostrophe’s or escape any data.  It’s just handled and this is true if you have database columns that are text, date, or numeric.

PreparedStatements have a number of advantages besides the automatic formatting.  They help with security and SQL Injection attacks.  If you don’t know what those are just do a web search to learn more.  You can reuse PreparedStatements in code but in my testing it doesn’t save much time as it appears as if the database plugin saves them internally.  Regardless, there are so many reasons to be using PreparedStatements over straight SQL.

To recap:  A nil recordset always mean a database error has happened.  You need to check for for the error after every operation whether that be a Select, Insert, Update, or Delete statement.  Basically after every SQLSelect and SQLExecute statement.  Ideally you want to start moving all of your code to use PreparedStatements because of all of its advantages.

2018 Was a Weird Year

I hope everyone’s holiday season was good.  We’re approaching the end of 2018 and I find it nice to reflect on what’s happened and what we’ve accomplished this year.

Looking Back

Let’s start off with the blog posts.  I did 41 (well now 42) blog posts in 2018.  Five were about Xojo releases.  Four were BKeeney Software product releases.  Four posts were about the Xojo Developers Conference.  The rest were a variety of Xojo related topics.

The most highly commented blog post was from June called Chasing Xojo where I lamented that Xojo, at least until that point, seemed to be a less stable when it came to Windows and Linux due to major revamping of the drawing systems on both platforms.  In Windows, Xojo doesn’t flicker as much but the struggle to get speed was a concern for all of 2018.  In Linux, the switch to GTK 3 wasn’t as smooth as we could have hoped.

The most viewed blog post was from August called Xojo 2018 Release 2 where I did my usual review of the most recent release of Xojo.  I heavily criticized Xojo for their poor documentation in that release.  I received plenty of blowback on that one.  But I think the end result is that R3 and R4 documentation was much better.

We released two new products with BKS Report Studio and BKS Tab Control.  Report Studio is our reporting utility meant for end-users for macOS and Windows and it was built using the award winning Shorts reporting classes (also a blog post).  The Tab Control is a canvas subclass that replaces, and extends, the built-in Xojo tab control in many ways and was our attempt at replaced the old CustomTabControl that many use but is unusable for HiDPI apps.

The other major release of the year was ARGen 3.0.  ARGen is our utility to create Xojo projects that creates ActiveRecord objects.  Among the many changes was the ability to generate ActiveRecord objects for iOS projects, supporting GUID primary keys, and the ability to include Audit Trail, Localization, and Database Update modules that help in many products.  We use ActiveRecord in practically every project and having the ability to generate some basic desktop and web UI is a huge time saver.

2018 sure seemed like a mixed bag for Xojo.  The Windows drawing issues took up a good chunk of the year and I think R4 was the first solid Windows release (although I still have 2 client apps that won’t remote debug in R4).  I can’t imagine the amount of effort that Xojo and the community put into getting Windows drawing fixed.

64-bit remote debugging became a reality for all targets this year.  64-bit compiling isn’t the huge gain that many in the community hoped for but then we always want more.  We just have to remember that 64-bit doesn’t necessarily mean ‘faster’.  At least the debugger works and that’s not nothing.

Dark Mode came soon after the release of Mojave.  The IDE works in Dark Mode and we were given many of the tools to implement it in our own projects.  Dark Mode only works in MacOS but some are already clamoring for it in Windows too.  It’s still to early to tell if Dark Mode is a hit on Mojave much less in xojo.

Looking Forward

What is 2019 going to bring us?  For one, we’re almost finished with a fairly significant update to Formatted Text Control and after that’s released we’ll start with an even bigger version 4 update to the venerable word processing control to bring it up to date and extend its capabilities to make it even more powerful.

We have a number of large consulting projects that have been in gestation for many months and years.  It will be nice to have a big project or two to keep us busy.

With the release of Web 2.0 I will redo all of our Xojo training videos related to web.  They’ve been outdated for a while but it’s not worth redoing the videos until Xojo releases Web 2.0.  If they release Android I’ll start on at least some intro videos for that too.  This might finally be the year that I redo the remaining Real Studio videos.  No doubt I’ll redo them just before a major IDE change.  🙂

What do I expect from Xojo?  That’s a tough question to answer since they’re so damn secretive now.  I expect Web 2.0 to show up in time for XDC (so maybe release 2?).  I think it will be pretty solid in the first release but it wouldn’t expect it to be good until the following release.

I also think that at XDC we’ll get an alpha of InterOps but not anything other than another dog and pony show for Android.  Targeting another platform is long and tedious process and involves some serious IDE work.  How much of the iOS editors can they use?  I can only guess but at first blush I say not much.

Some of Android’s success may hinge on getting iOS to use the global framework and away from the Xojo Framework.  Nothing like rewriting an entire framework while keeping backwards compatibility.  The more I think about it the more I think the iOS rework is put on hold until Android is released.  

Which leads to API 2.0 in general.  We’ve already seen some of the first new controls to use API 2.0.  URLConnection was introduced in 2018 R4 with mixed success.  I would expect more API 2.0 controls to show up.

So what do you think?  Was 2018 a successful year for Xojo?  What do you see happening in 2019?

Xojo 2018 Release 4

Xojo 2018 Release 4 hit the internet this week.  This relatively small (84 bug fixes, 21 changes, 5 new items, and 11 doc and example changes) update is a nice end of year release that may or may not satisfy your Xojo dreams.  Let’s get into the highlights.

Of the new items list the big one is the new URLConnection class.  The URLConnection class works with the HTTP 1.1+ protocol and works with http and https connections.  This is a replacement for the Xojo.Net.HTTPSocket and brings back one of the things many developers missed about the old HTTPSocket class – Synchronous communications – using the SendSync method.  

SendSync is a concession by Xojo with the caveat that the application may appear to freeze while running this method.  The regular, and probably the better, Send method is asynchronous and does not freeze the app.  Admittedly the async way is the better way but for many developers the synchronous method is easier to implement and ‘good enough’ for their use.  Still, consider using the async method.

The Screen class now has the ScaleFactor property.  There are two new global constants: AppSupportsDarkMode and AppSupportsHiDPI  that are pretty self explanatory.

iOS builds now use the iOS 12.1 SDK.  macOS builds now use the 10.14 SDK for 64-bit builds.

There are couple of changes that are noteworthy.  The first being that the Windows IDE can now successfully build large projects for Linux 64-bit and ARM targets (frankly I didn’t know this was a problem but I bet that ‘large’ is the key word).  Any remaining threads are now killed after the app.close event (possibly a reason why some apps in macOS crash after they quit?).  EnableMenuItems no longer fires needlessly on every keypress in Windows.  Lingua and Remote Debugger Stub have been updated to work with Dark Mode on macOS.

There are 84 bug fixes in this release.  The more important ones (at least in my opinion):  The Build folder is properly emptied between build runs.  Remote Debugging to a Raspberry Pi no longer randomly crashes when stopping at a breakpoint.  Browsers that have disconnected from the web app will now reload the web app so they don’t appear frozen.  There are also a couple dozen IDE bug fixes to the Inspector, Navigator, Find & Replace and a number of the editors.

As with any new release you need to thoroughly test your projects before doing a public release.  It was noted during the beta period that the Einhugur Search Control didn’t work properly in Mojave but has since been fixed.  We had one large project not work when remote debugging from Mac to Windows but I haven’t had time to track it down.  If you have found any new issues with R4 please submit a Feedback report right away!

Happy coding!

XDC 2019 Session List

The session list for the 2019 Xojo Developers Conference (XDC) was released today at https://www.xojo.com/xdc/sessions/.  Take a look at this interesting list.

I’ve been attending Xojo developer conferences for twelve plus years (don’t remember what my first XDC was – maybe 2004?).  Each one is unique and the topics are usually interesting but do tend to be repetitive from year to year at times.  The session topics for XDC 2019 seem to be more unique than past years.

Obviously Geoff will do his keynote address and talk about what they’ve done in the past year, what they’re currently working, and what’s coming up (sometime) in the future.  There is a session each for Android, Web 2.0, API 2.0, beyond Linux, everything MS Windows, and more by the Xojo staff.

What’s left is an intriguing list of sessions that will be tough to figure out what I want to attend and which ones I can wait to see recorded (assuming they’re recorded again).  I can’t remember an XDC I’ve looked forward to more.

Carol is doing a session on Database Topics for Programmers and I’m doing one called “Xojo Mistakes We All Regret Later”.  My alternative title is “Thankfully time travel doesn’t exist otherwise my future self will no doubt come back to murder me for these stupid programming mistakes I’ve done.”

If you’ve never been to an XDC I highly recommend it.  You will get to meet some of the best Xojo developers on the planet, talk Xojo non-stop for 3 (or more) days on end, talk to Xojo staff, and have fun.  Of course that last point is mostly because of the first three.  You won’t find a bigger concentration of Xojo developers on the planet!

I hope to see you all in Miami in the first week of May.  What sessions are you excited about?

What Topics Do You Want Covered?

One of the joys of doing a blog for close to eleven years is that I feel like I’ve talked about a lot of topics and people ‘know me’ fairly well.  I always get a thrill when people tell me they’ve read this blog.  That is so cool and I thank you for your valuable time!

As many of you know I do a quick review of every Xojo release.  I often do a blurbs about updates to our own products.  Occasionally I even rant about things (you should see the posts where I never hit the Publish button!).

When I had a column in Xojo Developer magazine this blog was a convenient place to discuss the ideas from the column.  But writing a reoccurring column is tough.  Keeping a blog going for eleven years seems to be even harder.  I’ve been writing fewer and fewer posts and I’d like to change that trend.

At one point I thought about taking a topic in the Xojo Forums and talking about it in-depth  here.  We’ve been busy doing consulting work so I spend far less time on the forums than I used to but it might be an interesting way to generate new posts.

So, my fellow Xojo developers, what topics would you like to see me tackle?  Topics can include my opinions on the future of Xojo, how’s the 3rd party market doing, why did we choose <x> or <y> over <z>, or anything in between.  I’ll let you be in the drivers seat for while.

Some ground rules:

  • If you’re rude to me, my staff, or Xojo staff I’ll just delete the comment, ban you, and move on.
  • Keep it simple – this is a blog and not a magazine.  Though that doesn’t mean I can’t do a multi-part blog post.
  • I reserve judgement to make more rules as I think of them.  😉

So what topics do you have?