4

I usually forget to start/stop time trackers when I'm working on different projects and tasks.

So I think it would be better if there is an app that can automatically track my screen time on each desktop. That means I can create a separate desktop for each task, and when I switch to it, the time tracker would automatically start. When I switch to another desktop, or when I lock the screen, or when the computer sleeps, it should automatically stop the timer.

7
  • 2
    I don't know who decided the linked question with 12 answers was the same as this question. It's clearly not the same. Those answers have nearly 0 to do with this question. None of those answers solve tracking time per desktop. @Noel Pure - if you want an answer to your question, PM me and I'll share my desktop time tracking solution with you, because since the question is closed, I can't answer it.
    – hepcat72
    Commented Feb 11, 2021 at 14:18
  • 4 years after your question, did you find something? @hepcat72 how can I PM you?
    – Iván
    Commented Feb 14 at 1:40
  • You can answer in this post apple.stackexchange.com/questions/464201/…
    – Iván
    Commented Feb 14 at 1:46
  • 1
    Ok. It's a little involved but I think I may have written about it somewhere once. I won't be at my desk for a couple hours so remind me to answer your other question if I forget.
    – hepcat72
    Commented Feb 14 at 12:36
  • It's an old answer that needs a lot more detail to be an answer for this question, but I was poking around while having my morning coffee and I did find what I'd written about this before. Take a look: stackoverflow.com/a/66036144/2057516 I'll try to craft a more comprehensive answer in the other question later.
    – hepcat72
    Commented Feb 14 at 13:55

2 Answers 2

1

I have an AppleScript that I run once a minute via a cron job that tracks my current desktop. I use this solution for the following purposes:

  1. I use each desktop for work on a different project and switch between them to work on those different projects. (Thus, the ability to track time spent on a desktop is a great stand-in for project time tracking.)
  2. Each project uses a mostly overlapping assortment of the same set of apps, so app trackers are wholly insufficient for app tracking being a stand-in for work on a project.

There are a number of hurdles to overcome when you want to track time spent on different desktops:

  1. Desktops cannot be named or otherwise identified by the OS via AppleScript. You can't even get the desktop number.
  2. There are no reliable third party tools to track time spent on each desktop.
  3. Using windows of different apps on each desktop to "label" desktops cannot typically be read in mission control to identify desktops manually and updating the desktop image is not an easy solution when the projects on the desktops frequently change in name and concurrent number.
  4. If using app windows to label desktops, some apps do not return their windows to their previous desktop after reboot.
  5. Window-based "desktop labels" can get buried among all the windows on a desktop, making it difficult to always be able to identify a desktop manually.

To label desktops, I chose to put the project name in a huge font in various Stickies windows, so that it's easily legible in the desktop thumbnails in Mission Control. This can be used to mitigate a number of the issues above:

  • I hide the stickie window behind my Dock so that it's rarely buried by other windows in mission control.
  • I duplicate the desktop name in small superscripted text that pokes out from under the left side of the dock so that I can almost always identify the current desktop outside of mission control.
  • In order to identify the correct stickies window (using AppleScript) that "labels" a desktop, I append "dtop" to the project name in an extremely (i.e. invisible) font, so if I have multiple Stickies windows on a desktop, I know which one has the project name.
  • The titlebar in Stickies is small enough that you can still see the superscripted label when you put the Stickie under the dock. And in mission control, the dock is not visible in the desktop thumbnails, making the large font easily legible in each thumbnail.

Here is an example screenshot of what the desktop thumbnails look like with the stickies. Note how all the app windows are typically above the dock, making the stickie windows easily viewed and legible:

enter image description here

The only issue with Stickies (in my experience) is that after reboot, all Stickies windows end up on the first desktop. I wrote a separate AppleScript to restore their desktop distribution (but that's a separate question).

To track the current desktop, I have a rather sophisticated script. I won't get into the details, because they are ancillary to the question, but this is the "function" I use to get the current desktop. Note, this assumes that the project name contains no spaces (i.e. it's just one word). You can customize it to change this, if you wish. Here is the AppleScript that, when run, results in the desktop name. To keep things simple, I removed the error handling.

set dtop to my getCurrentDesktop()

on getCurrentDesktop()
    -- dtopstr = the string anywhere on the first line of the sticky that identifies it as containing the desktop name
    set dtopstr to "dtop"
    set dname to "unmonitored"  -- Default desktop name (i.e. "no stickie")

    tell application "System Events"
        --obtain the stickie with the desktop name
        set dstr to name of first item of (windows of application process "Stickies" of application "System Events" whose name contains dtopstr)
            
        --Parse the desktop name from the stickie
        set astid to AppleScript's text item delimiters
        set AppleScript's text item delimiters to " "
        set dname to first item of (dstr's text items)
        set AppleScript's text item delimiters to astid
    end tell
    
    return dname
end getCurrentDesktop

Note that there are a number of fancy features I added to the script. I track cursor movement to identify idle time. I designated a few apps that are project independent, such as:

  • Zoom
  • Mail
  • Slack
  • Calendar
  • Certain Safari windows with certain names, like ones associated with HR, etc

I categorize those apps using a data structure and count the time in those apps based on whether the apps are simply running or are "frontmost". Here is an example of that datastructure initialization in AppleScript:

set customStatusChecks to {¬
    {"meeting", ¬
        {¬
            {"running", "zoom.us", {"Zoom Meeting"}}}}, ¬
    {"communication", ¬
        {¬
            {"front", "Mail", {}}, ¬
            {"front", "gen-help", {}}, ¬
            {"front", "Slack", {}}}}, ¬
    {"planning", ¬
        {¬
            {"front", "Calendar", {}}, ¬
            {"front", "Trello", {}}}}, ¬
    {"overhead", ¬
        {¬
            {"front", "Princeton IT Self Service", {}}, ¬
            {"front", "Safari", {"Holiday Schedule", "OIT Store", "Self Service", "TigerCard", "Tiger Transit"}}}}}

I don't want to get into all of the details of the fancy features I added, but to summarize them, just have a look at the main body of code, which is fairly short. I set the return to a different variable and at the end, I just join every datum as a tab-delimited string:

set customStatuses to my getCustomStatuses(customStatusChecks)
set dtop to my getCurrentDesktop()
set secs to my getSecondsSinceEpoch()
set {mpos, mntr} to my getMousePosition()
set {capp, cwin} to my getCurrentApp()

set lmsg to join(tab, {secs, mpos, dtop, mntr, capp, cwin, (every item of customStatuses)})

Here is a sample of the project log file:

1660158662  1240,362    TRACEBASE   DELL P2721Q, (1)    Safari  Update README.md by aleifer · Pull Request #109 · PrincetonUniversity/neuron-graph  none    none    none    none
1660158722  1664,471    TRACEBASE   DELL P2721Q, (1)    Safari  Update README.md by aleifer · Pull Request #109 · PrincetonUniversity/neuron-graph  none    none    none    none
1660158782  150,909 TRACEBASE   DELL P2721Q, (1)    Electron    peak_group_label.py — tracebase none    none    none    none
1660158842  329,332 TRACEBASE   DELL P2721Q, (1)    Terminal    Terminal — ttys000  none    none    none    none
1660158902  822,532 TRACEBASE   DELL P2721Q, (1)    Terminal    Terminal — ttys000  none    none    none    none
1660158962  974,305 TRACEBASE   DELL P2721Q, (1)    Electron    test_models.py — tracebase  none    none    none    none
1660159023  1617,1361   TRACEBASE   DELL P2721Q, (1)    Slack   Slack | funconn | Princeton NPLC    none    communication   none    none
1660159083  1823,610    PRODUCTIVITY    DELL P2721Q, (1)    TextEdit    Untitled 67 none    none    none    none
1660159143  504,875 PRODUCTIVITY    DELL P2721Q, (1)    TextEdit    project_time_tracking_notes.txt none    none    none    none

Note that is supports multiple monitors (reported in the cursor position) and it reports the status of each custom-tracked app/window from the customStatusChecks data structure as the last set of columns.

To set it up via cron job for weekdays, you add this line to crontab -e:

* * * * MON-FRI osascript /Users/<username>/logProjectActivity.scpt >> /Users/<username>/project_log.txt 2>> /Users/<username>/project_log.err

This runs the script once a minute on weekdays.

To be able to use the data, I wrote a perl script to turn the tab-delimited output project_log.txt into different types of bar plots to depict how much time I spend on each project (i.e. desktop) over a period of time (e.g. the past week). Here's an example of the output (also a separate question):

enter image description here enter image description here

Note that in the second plot, I set a limit for the length of each day. It automatically fills with idle time so that each day is the same length, but if I work overtime, you can see that the length of that day is longer.

I really should make a github repo for this code. PM me to get a full copy of the script. I haven't edited it yet to make it distributable. It has a few hard-coded paths in it and it has my app categorizations that pertain specifically to my job. All that would have to be customized per person.

As a side-note, I haven't checked on my project log in some time, and it hasn't apparently been logging for awhile because one of the directory names changed in the path to the log, but I'll be fixing that today.^

^ I had a "typo" in the path I used. My project log is still good and active. Though I will note that there is an issue with the identification of some apps. For example, the "VS Code" app reports as "Electron", and my Fluid.app apps, while they have different names, all report as "Fluid". I have fixed this in some of my other AppleScripts, just not this one.

UPDATE 2/28/2024: I just posted the log script as a gist. I have not yet published the perl script that creates the plots:

~logProjectActivity.osa~

See UPDATE 3/17/2024 below.

UPDATE 3/7/2024: I just pulled up my perl script that generates the plots and I noted that it processes the customStatusChecks using left to right precedence. I'd forgotten about that. It takes the first non-"none", non-"unknown" custom state on each line as the "active project" for that minute. If they are all "none", "unknown", or empty, it falls back to the desktop project name.

The perl script is named timeTrackingPlots.pl. It's usage:

$ perl timeTrackingPlots.pl 
timeTrackingPlots.pl [OPTIONS]

  <file*...>...       Input file(s).
  -c <sfx>            [.1709822965.days.txt] Outfile suffix appended to file names supplied to [-i].
  -p <sfx>            [.1709822965.projects.txt] Outfile suffix appended to file names supplied to [-i].
  -d <int>            [7] Number of days to include.
  --run               Run the script.
  --help              Print general info and file formats.
  --extended [<cnt>]  Print detailed usage.

Example:

tail -n 11000 project_log.txt | perl timeTrackingPlots.pl

(I tail the log file because I haven't implemented log file cycling, and it's huge. A line for every minute means 10,800 lines per week, so I tailed 11,000.)

It needs a few documentation updates and an installer (because it uses my personal CommandLineInterface.pm package, which I haven't independently published yet, and has a dependency on gnuplot and the macOS open command (because it automatically opens the plots in Preview.app)).

I developed this whole "overhead project" during the pandemic, and using the plotting script now, I realize that having a hybrid work environment presents a new challenge: incorporating time data from 2 different computers, each with their own activity data. Ugh.

I will eventually get around to putting this all in a github repo, but if anyone wants a copy of the plotting script, let me know.

UPDATE 3/17/2024:

GitHub repo is up: https://github.com/hepcat72/desktopTimeTracker/

8
  • 1
    This is incredible and even compares favorably with some of the commercial solutions on our canonical question for good time tracking scripts and tools.
    – bmike
    Commented Feb 27 at 13:36
  • High praise. Thanks. I feel like that's rare for me on stack sites and other forums. I just was never satisfied with any of the current time tracking apps. And this pairs nicely with my slack status updates. I rigged the wall switch in my home office to update my slack status (as WFH, "stepped out", or inactive), and I have an iBeacon in my work office that does the same thing, but based on my iBeacon-detected presence. That would probably be nice to include in my stats, though it would make the script less distributable, so perhaps a separate log script to add-in that context.
    – hepcat72
    Commented Feb 27 at 14:34
  • 1
    OK, I just published the log script as a gist. I'll append a link in the answer...
    – hepcat72
    Commented Feb 28 at 14:40
  • Just added a description of the perl plotting script I wrote as a way to generate the plots. Have not yet published it.
    – hepcat72
    Commented Mar 7 at 15:00
  • Nice! I’m in the middle of trying out seaborn.pydata.org for a work project…. Plots are so useful.
    – bmike
    Commented Mar 13 at 18:22
-1

I don't know about a solution that tracks time per desktop but what I use is Observe (https://qotoqot.com/qbserve/). It tracks the time you spend in any application and you can add filters so screen time in one app is allocated to a specific project. You can even define working paths. So every time you work on a file in specific directory it also gets allocated to a specific project.

3
  • But this doesn't answer the question. qbserve does not track time spent on desktops.
    – hepcat72
    Commented Feb 11, 2021 at 14:18
  • Let’s find a question that asks for this flexibility. It seems a great tool, just not the slicing this person needs per screen
    – bmike
    Commented Feb 27 at 13:26
  • If this tool isn’t posted here - apple.stackexchange.com/q/9175/5472 I would upvote things! If it’s there, please edit the post to explain your use case so it gets bumped.
    – bmike
    Commented Feb 27 at 13:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .