mirror of
https://github.com/ckaczor/Blog.git
synced 2026-01-13 17:22:16 -05:00
576 lines
13 KiB
HTML
576 lines
13 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Work Indicator</title>
|
||
<meta name="description" content="Code, Critters, and whatever I feel like writing about.">
|
||
<link rel="alternate" href="/Blog/feed/feed.xml" type="application/atom+xml" title="Chris Kaczor">
|
||
|
||
<link rel="apple-touch-icon" sizes="180x180" href="/Blog/img/apple-touch-icon.png?v=2">
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/Blog/img/favicon-32x32.png?v=2">
|
||
<link rel="icon" type="image/png" sizes="16x16" href="/Blog/img/favicon-16x16.png?v=2">
|
||
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
|
||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||
|
||
<meta name="generator" content="Eleventy v3.0.0">
|
||
|
||
|
||
<style>
|
||
/**
|
||
* okaidia theme for JavaScript, CSS and HTML
|
||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||
* @author ocodia
|
||
*/
|
||
|
||
code[class*="language-"],
|
||
pre[class*="language-"] {
|
||
color: #f8f8f2;
|
||
background: none;
|
||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||
font-size: 1em;
|
||
text-align: left;
|
||
white-space: pre;
|
||
word-spacing: normal;
|
||
word-break: normal;
|
||
word-wrap: normal;
|
||
line-height: 1.5;
|
||
|
||
-moz-tab-size: 4;
|
||
-o-tab-size: 4;
|
||
tab-size: 4;
|
||
|
||
-webkit-hyphens: none;
|
||
-moz-hyphens: none;
|
||
-ms-hyphens: none;
|
||
hyphens: none;
|
||
}
|
||
|
||
/* Code blocks */
|
||
pre[class*="language-"] {
|
||
padding: 1em;
|
||
margin: .5em 0;
|
||
overflow: auto;
|
||
border-radius: 0.3em;
|
||
}
|
||
|
||
:not(pre) > code[class*="language-"],
|
||
pre[class*="language-"] {
|
||
background: #272822;
|
||
}
|
||
|
||
/* Inline code */
|
||
:not(pre) > code[class*="language-"] {
|
||
padding: .1em;
|
||
border-radius: .3em;
|
||
white-space: normal;
|
||
}
|
||
|
||
.token.comment,
|
||
.token.prolog,
|
||
.token.doctype,
|
||
.token.cdata {
|
||
color: #8292a2;
|
||
}
|
||
|
||
.token.punctuation {
|
||
color: #f8f8f2;
|
||
}
|
||
|
||
.token.namespace {
|
||
opacity: .7;
|
||
}
|
||
|
||
.token.property,
|
||
.token.tag,
|
||
.token.constant,
|
||
.token.symbol,
|
||
.token.deleted {
|
||
color: #f92672;
|
||
}
|
||
|
||
.token.boolean,
|
||
.token.number {
|
||
color: #ae81ff;
|
||
}
|
||
|
||
.token.selector,
|
||
.token.attr-name,
|
||
.token.string,
|
||
.token.char,
|
||
.token.builtin,
|
||
.token.inserted {
|
||
color: #a6e22e;
|
||
}
|
||
|
||
.token.operator,
|
||
.token.entity,
|
||
.token.url,
|
||
.language-css .token.string,
|
||
.style .token.string,
|
||
.token.variable {
|
||
color: #f8f8f2;
|
||
}
|
||
|
||
.token.atrule,
|
||
.token.attr-value,
|
||
.token.function,
|
||
.token.class-name {
|
||
color: #e6db74;
|
||
}
|
||
|
||
.token.keyword {
|
||
color: #66d9ef;
|
||
}
|
||
|
||
.token.regex,
|
||
.token.important {
|
||
color: #fd971f;
|
||
}
|
||
|
||
.token.important,
|
||
.token.bold {
|
||
font-weight: bold;
|
||
}
|
||
.token.italic {
|
||
font-style: italic;
|
||
}
|
||
|
||
.token.entity {
|
||
cursor: help;
|
||
}
|
||
/*
|
||
* New diff- syntax
|
||
*/
|
||
|
||
pre[class*='language-diff-'] {
|
||
--eleventy-code-padding: 1.25em;
|
||
padding-left: var(--eleventy-code-padding);
|
||
padding-right: var(--eleventy-code-padding);
|
||
}
|
||
.token.deleted {
|
||
background-color: hsl(0, 51%, 37%);
|
||
color: inherit;
|
||
}
|
||
.token.inserted {
|
||
background-color: hsl(126, 31%, 39%);
|
||
color: inherit;
|
||
}
|
||
|
||
/* Make the + and - characters unselectable for copy/paste */
|
||
.token.prefix.unchanged,
|
||
.token.prefix.inserted,
|
||
.token.prefix.deleted {
|
||
-webkit-user-select: none;
|
||
user-select: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding-top: 2px;
|
||
padding-bottom: 2px;
|
||
}
|
||
.token.prefix.inserted,
|
||
.token.prefix.deleted {
|
||
width: var(--eleventy-code-padding);
|
||
background-color: rgba(0, 0, 0, 0.2);
|
||
}
|
||
|
||
/* Optional: full-width background color */
|
||
.token.inserted:not(.prefix),
|
||
.token.deleted:not(.prefix) {
|
||
display: block;
|
||
margin-left: calc(-1 * var(--eleventy-code-padding));
|
||
margin-right: calc(-1 * var(--eleventy-code-padding));
|
||
text-decoration: none; /* override del, ins, mark defaults */
|
||
color: inherit; /* override del, ins, mark defaults */
|
||
}
|
||
/* Defaults */
|
||
:root {
|
||
--font-family: Roboto, sans-serif;
|
||
--font-family-monospace: Consolas, Menlo, Monaco, Andale Mono WT,
|
||
Andale Mono, Lucida Console, Lucida Sans Typewriter, DejaVu Sans Mono,
|
||
Bitstream Vera Sans Mono, Liberation Mono, Nimbus Mono L, Courier New,
|
||
Courier, monospace;
|
||
}
|
||
|
||
/* Theme colors */
|
||
:root {
|
||
--color-gray-20: #e0e0e0;
|
||
--color-gray-50: #c0c0c0;
|
||
--color-gray-90: #333;
|
||
|
||
--background-color: #fff;
|
||
|
||
--text-color: var(--color-gray-90);
|
||
--text-color-link: #082840;
|
||
--text-color-link-active: #5f2b48;
|
||
--text-color-link-visited: #17050f;
|
||
|
||
--syntax-tab-size: 2;
|
||
}
|
||
|
||
@media (prefers-color-scheme: dark) {
|
||
:root {
|
||
--color-gray-20: #e0e0e0;
|
||
--color-gray-50: #c0c0c0;
|
||
--color-gray-90: #dad8d8;
|
||
|
||
/* --text-color is assigned to --color-gray-_ above */
|
||
--text-color-link: #1493fb;
|
||
--text-color-link-active: #6969f7;
|
||
--text-color-link-visited: #a6a6f8;
|
||
|
||
--background-color: #15202b;
|
||
}
|
||
}
|
||
|
||
/* Global stylesheet */
|
||
* {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
@view-transition {
|
||
navigation: auto;
|
||
}
|
||
|
||
html,
|
||
body {
|
||
padding: 0;
|
||
margin: 0 auto;
|
||
font-family: var(--font-family);
|
||
color: var(--text-color);
|
||
background-color: var(--background-color);
|
||
}
|
||
html {
|
||
overflow-y: scroll;
|
||
}
|
||
body {
|
||
max-width: 60em;
|
||
}
|
||
|
||
/* https://www.a11yproject.com/posts/how-to-hide-content/ */
|
||
.visually-hidden {
|
||
clip: rect(0 0 0 0);
|
||
clip-path: inset(50%);
|
||
height: 1px;
|
||
overflow: hidden;
|
||
position: absolute;
|
||
white-space: nowrap;
|
||
width: 1px;
|
||
}
|
||
|
||
p:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
p {
|
||
line-height: 1.5;
|
||
}
|
||
|
||
li {
|
||
line-height: 1.5;
|
||
}
|
||
|
||
a[href] {
|
||
color: var(--text-color-link);
|
||
}
|
||
a[href]:visited {
|
||
color: var(--text-color-link-visited);
|
||
}
|
||
a[href]:hover,
|
||
a[href]:active {
|
||
color: var(--text-color-link-active);
|
||
}
|
||
|
||
main {
|
||
padding: 1rem;
|
||
}
|
||
footer {
|
||
padding-bottom: 1rem;
|
||
padding-left: 1rem;
|
||
padding-right: 1rem;
|
||
font-size: 0.75rem;
|
||
}
|
||
main :first-child {
|
||
margin-top: 0;
|
||
}
|
||
|
||
header {
|
||
border-bottom: 1px dashed var(--color-gray-20);
|
||
}
|
||
header:after {
|
||
content: '';
|
||
display: table;
|
||
clear: both;
|
||
}
|
||
|
||
.links-nextprev {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
gap: 0.5em 1em;
|
||
list-style: '';
|
||
border-top: 1px dashed var(--color-gray-20);
|
||
padding: 1em 0;
|
||
}
|
||
.links-nextprev > * {
|
||
flex-grow: 1;
|
||
}
|
||
.links-nextprev-next {
|
||
text-align: right;
|
||
}
|
||
|
||
table {
|
||
margin: 1em 0;
|
||
}
|
||
table td,
|
||
table th {
|
||
padding-right: 1em;
|
||
}
|
||
|
||
pre,
|
||
code {
|
||
font-family: var(--font-family-monospace);
|
||
}
|
||
pre:not([class*='language-']) {
|
||
margin: 0.5em 0;
|
||
line-height: 1.375; /* 22px /16 */
|
||
-moz-tab-size: var(--syntax-tab-size);
|
||
-o-tab-size: var(--syntax-tab-size);
|
||
tab-size: var(--syntax-tab-size);
|
||
-webkit-hyphens: none;
|
||
-ms-hyphens: none;
|
||
hyphens: none;
|
||
direction: ltr;
|
||
text-align: left;
|
||
white-space: pre;
|
||
word-spacing: normal;
|
||
word-break: normal;
|
||
overflow-x: auto;
|
||
}
|
||
code {
|
||
word-break: break-all;
|
||
}
|
||
|
||
/* Header */
|
||
header {
|
||
display: flex;
|
||
gap: 1em 0.5em;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
padding: 1em;
|
||
}
|
||
.home-link {
|
||
font-size: 1em; /* 16px /16 */
|
||
font-weight: 700;
|
||
margin-right: 2em;
|
||
}
|
||
.home-link:link:not(:hover) {
|
||
text-decoration: none;
|
||
}
|
||
|
||
/* Nav */
|
||
.nav {
|
||
display: flex;
|
||
padding: 0;
|
||
margin: 0;
|
||
list-style: none;
|
||
}
|
||
.nav-item {
|
||
display: inline-block;
|
||
margin-right: 1em;
|
||
}
|
||
.nav-item a[href]:not(:hover) {
|
||
text-decoration: none;
|
||
}
|
||
.nav a[href][aria-current='page'] {
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* Posts list */
|
||
.postlist {
|
||
list-style: none;
|
||
padding: 0;
|
||
}
|
||
.postlist-item {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: baseline;
|
||
margin-bottom: 2em;
|
||
}
|
||
.postlist-item:last-child {
|
||
margin-bottom: 0em;
|
||
}
|
||
.postlist-item:before {
|
||
display: inline-block;
|
||
pointer-events: none;
|
||
line-height: 100%;
|
||
text-align: right;
|
||
}
|
||
.postlist-date,
|
||
.postlist-item:before {
|
||
font-size: 0.8125em; /* 13px /16 */
|
||
color: var(--color-gray-90);
|
||
}
|
||
.postlist-date {
|
||
word-spacing: -0.5px;
|
||
}
|
||
.postlist-link {
|
||
font-size: 1.1875em; /* 19px /16 */
|
||
font-weight: 700;
|
||
flex-basis: calc(100% - 1.5rem);
|
||
padding-right: 0.5em;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.postlist-read-more {
|
||
text-decoration: none;
|
||
font-size: 0.8125em;
|
||
flex-basis: 100%;
|
||
}
|
||
|
||
.postlist-read-more:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.postlist-link:hover {
|
||
text-decoration: underline;
|
||
text-underline-position: from-font;
|
||
text-underline-offset: 0;
|
||
text-decoration-thickness: 1px;
|
||
}
|
||
.postlist-item-active .postlist-link {
|
||
font-weight: bold;
|
||
}
|
||
|
||
.postlist-byline {
|
||
flex-basis: 100%;
|
||
}
|
||
|
||
.postlist-tags {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
list-style-type: none;
|
||
gap: 0.5em;
|
||
font-size: 0.8125em;
|
||
padding-inline-start: 10px;
|
||
}
|
||
|
||
.postlist-tag {
|
||
text-decoration: none;
|
||
}
|
||
|
||
.postlist-tag:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
/* Tags */
|
||
.post-tag {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-transform: capitalize;
|
||
}
|
||
.postlist-item > .post-tag {
|
||
align-self: center;
|
||
}
|
||
|
||
/* Tags list */
|
||
.post-metadata {
|
||
display: inline-flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.5em;
|
||
list-style: none;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
.post-metadata time {
|
||
margin-right: 1em;
|
||
}
|
||
|
||
img {
|
||
max-width: 100%;
|
||
display: block;
|
||
margin: 0 auto;
|
||
}
|
||
img[height] {
|
||
height: auto;
|
||
}
|
||
img[width][height] {
|
||
height: auto;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<a href="#skip" class="visually-hidden">Skip to main content</a>
|
||
|
||
<header>
|
||
<a href="/Blog/" class="home-link">Chris Kaczor</a>
|
||
<nav>
|
||
<h2 class="visually-hidden" id="top-level-navigation-menu">Top level navigation menu</h2>
|
||
<ul class="nav">
|
||
<li class="nav-item">
|
||
<a href="/Blog/">
|
||
Home
|
||
</a>
|
||
</li>
|
||
<li class="nav-item">
|
||
<a href="/Blog/tags/">
|
||
Tags
|
||
</a>
|
||
</li>
|
||
<li class="nav-item">
|
||
<a href="/Blog/about/">
|
||
About
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
</header>
|
||
|
||
<main id="skip">
|
||
<heading-anchors>
|
||
|
||
<h1 id="work-indicator">Work Indicator</h1>
|
||
|
||
<ul class="post-metadata">
|
||
<li>
|
||
<time datetime="2018-03-19">19 March 2018</time>
|
||
</li>
|
||
<li>
|
||
<a href="/Blog/tags/code/" class="post-tag">Code</a>
|
||
</li>
|
||
</ul>
|
||
|
||
<p>I'm going to take a break from status windows for a little bit to cover my <a href="https://github.com/ckaczor/WorkIndicator">WorkIndicator</a> project.</p>
|
||
<p>I've been working remotely for almost 14 years now and my family found it hard to tell when I was working or on the phone. It often looks the same whether I'm working or not - I'm sitting at my computer, sometimes with my headset on. At some point I came across a <a href="https://www.hanselman.com/blog/IsDaddyOnACallABusyLightPresenceIndicatorForLyncForMyHomeOffice.aspx">blog post</a> by Scott Hanselman that described hooking up a status light to Lync and I was inspired to create something similar.</p>
|
||
<p>The first task was to find something I could use as a status light - after some research I settled on a <a href="https://www.delcomproducts.com/productdetails.asp?PartNumber=907241">USB HID Green/Yellow/Red Visual Indicator</a> from Delcom. I liked that it had a stoplight design and it came with a C# sample - perfect!</p>
|
||
<p>My main workflow is to connect to my work system using Microsoft Remote Desktop so the easiest way to detect if I am working or not is to look for the remote desktop window. I created a class that uses SetWinEventHook to get ObjectCreate, ObjectDestroy, and ObjectNameChanged events and watch for a window with the title of my remote desktop window. If the window was found I'd set the indicator lights to yellow, otherwise I'd set them to green. Lately I've been using a VM as well so I updated the code to be able to look for multiple window titles - if any of them are detected the light is set to yellow.</p>
|
||
<p>Originally there was also Skype integration - I was able to use the Skype API to detect if I was on a call and if the call was muted. If I was on a muted call the right light would be on, and if I wasn't muted the red light would blink. This made it easy for the kids to tell how quiet they needed to be when coming into the room. Unfortunately Skype no longer supports this API (and I'm not using Skype anymore anyways) so I removed this code from the project.</p>
|
||
<p>The application also has a tray icon with a menu so I can manually set my status - for example, I can select "talking" and the red light will blink. This is my workaround until I come up with something that'll work for my current phone setup.</p>
|
||
|
||
<ul class="links-nextprev">
|
||
<li class="links-nextprev-prev">← Previous<br>
|
||
<a href="/Blog/blog/system-temperature-status-window/">System Temperature Status Window</a>
|
||
</li>
|
||
|
||
<li class="links-nextprev-next">Next →<br>
|
||
<a href="/Blog/blog/laundry-monitor-hardware/">Laundry Monitor - Hardware</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</heading-anchors>
|
||
</main>
|
||
|
||
<footer>
|
||
<p>
|
||
Built with <a href="https://www.11ty.dev/">Eleventy v3.0.0</a>
|
||
</p>
|
||
</footer>
|
||
|
||
<!-- This page `/Blog/blog/work-indicator/` was built on 2024-11-21T23:16:50.533Z -->
|
||
<script type="module" src="/Blog/dist/rJ3_G-2ArF.js"></script>
|
||
</body>
|
||
</html> |