diff --git a/OBS.rc b/OBS.rc
index 9a2659a7..1fb237ee 100644
--- a/OBS.rc
+++ b/OBS.rc
@@ -162,6 +162,10 @@ BEGIN
PUSHBUTTON "Rename",IDC_RENAME,224,58,76,14
PUSHBUTTON "Remove",IDC_REMOVE,301,58,75,14
LTEXT "Settings.General.Restart",IDC_INFO,7,145,409,48,NOT WS_VISIBLE
+ CONTROL "Settings.General.Notification",IDC_NOTIFICATIONICON,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,172,94,108,10,WS_EX_RIGHT
+ CONTROL "Settings.General.NotificationMinimize",IDC_MINIZENOTIFICATION,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,146,110,134,10,WS_EX_RIGHT
END
IDD_SETTINGS_AUDIO DIALOGEX 0, 0, 427, 336
@@ -648,6 +652,7 @@ IDI_SOUND_MIC ICON "ui\\mic2.ico"
IDI_SOUND_MIC_MUTED ICON "ui\\mic2-muted.ico"
IDI_SOUND_DESKTOP ICON "ui\\speaker.ico"
IDI_SOUND_DESKTOP_MUTED ICON "ui\\speaker-muted.ico"
+IDI_ICON2 ICON "ui\\test2\\recording.ico"
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/OBS.vcxproj b/OBS.vcxproj
index c5a4748f..046fc8dd 100644
--- a/OBS.vcxproj
+++ b/OBS.vcxproj
@@ -299,6 +299,7 @@
+
diff --git a/OBS.vcxproj.filters b/OBS.vcxproj.filters
index 72150123..cc4d04a9 100644
--- a/OBS.vcxproj.filters
+++ b/OBS.vcxproj.filters
@@ -230,6 +230,9 @@
Shaders
+
+ Resources
+
diff --git a/Source/Main.h b/Source/Main.h
index 1fe725f6..56d929f3 100644
--- a/Source/Main.h
+++ b/Source/Main.h
@@ -27,6 +27,7 @@
#define ISOLATION_AWARE_ENABLED 1
#include
#include
+#include
#include
#include
diff --git a/Source/OBS.cpp b/Source/OBS.cpp
index c00cc85d..a4e29a6b 100644
--- a/Source/OBS.cpp
+++ b/Source/OBS.cpp
@@ -446,6 +446,16 @@ OBS::OBS()
0, 0, 0, 0, hwndMain, (HMENU)ID_SOURCES_TEXT, 0, 0);
SendMessage(hwndTemp, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
+ //-----------------------------------------------------
+ // notification area
+
+ bNotificationAreaIcon = false;
+ wmExplorerRestarted = RegisterWindowMessage(TEXT("TaskbarCreated"));
+ if (AppConfig->GetInt(TEXT("General"), TEXT("ShowNotificationAreaIcon"), 0) != 0)
+ {
+ ShowNotificationAreaIcon();
+ }
+
//-----------------------------------------------------
// populate scenes
@@ -661,6 +671,11 @@ OBS::~OBS()
pluginInfo.strFile.Clear();
}
+ if (AppConfig->GetInt(TEXT("General"), TEXT("ShowNotificationAreaIcon"), 0) != 0)
+ {
+ App->HideNotificationAreaIcon();
+ }
+
//DestroyWindow(hwndMain);
// Remember window state for next launch
@@ -1541,3 +1556,51 @@ void OBS::SetSourceRender(CTSTR sourceName, bool render)
}
}
}
+
+BOOL OBS::SetNotificationAreaIcon(DWORD dwMessage, int idIcon, const String &tooltip)
+{
+ NOTIFYICONDATA niData;
+ ZeroMemory(&niData, sizeof(NOTIFYICONDATA));
+ niData.cbSize = sizeof(niData);
+ niData.hWnd = hwndMain;
+ niData.uID = 0;
+ if (NIM_DELETE != dwMessage)
+ {
+ niData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+ niData.uCallbackMessage = OBS_NOTIFICATIONAREA;
+ niData.hIcon = LoadIcon(hinstMain, MAKEINTRESOURCE(idIcon));
+ lstrcpy(niData.szTip, tooltip);
+ }
+ return Shell_NotifyIcon(dwMessage, &niData);
+}
+
+BOOL OBS::ShowNotificationAreaIcon()
+{
+ BOOL result = FALSE;
+ int idIcon = bRunning ? IDI_ICON2 : IDI_ICON1;
+ String tooltip(TEXT("OBS"));
+
+ if (!bNotificationAreaIcon)
+ {
+ bNotificationAreaIcon = true;
+ result = SetNotificationAreaIcon(NIM_ADD, idIcon, tooltip);
+ }
+ else
+ {
+ result = SetNotificationAreaIcon(NIM_MODIFY, idIcon, tooltip);
+ }
+ return result;
+}
+
+BOOL OBS::UpdateNotificationAreaIcon()
+{
+ if (bNotificationAreaIcon)
+ return ShowNotificationAreaIcon();
+ return TRUE;
+}
+
+BOOL OBS::HideNotificationAreaIcon()
+{
+ bNotificationAreaIcon = false;
+ return SetNotificationAreaIcon(NIM_DELETE, 0, TEXT(""));
+}
diff --git a/Source/OBS.h b/Source/OBS.h
index 5dec19cc..4f6deaa3 100644
--- a/Source/OBS.h
+++ b/Source/OBS.h
@@ -341,6 +341,7 @@ enum
OBS_SETSOURCEORDER,
OBS_SETSOURCERENDER,
OBS_UPDATESTATUSBAR,
+ OBS_NOTIFICATIONAREA,
};
//----------------------------
@@ -656,6 +657,12 @@ private:
bool QueryNewAudio(QWORD ×tamp);
void MainAudioLoop();
+ //---------------------------------------------------
+ // notification area icon
+ UINT wmExplorerRestarted;
+ bool bNotificationAreaIcon;
+ BOOL SetNotificationAreaIcon(DWORD dwMessage, int idIcon, const String &tooltip);
+
//---------------------------------------------------
// random bla-haa
@@ -930,6 +937,10 @@ public:
virtual void ReportMicVolumeChange(float level, bool muted, bool finalValue);
virtual void ReportDesktopVolumeChange(float level, bool muted, bool finalValue);
+ // notification area icon functions
+ BOOL ShowNotificationAreaIcon();
+ BOOL UpdateNotificationAreaIcon();
+ BOOL HideNotificationAreaIcon();
};
LONG CALLBACK OBSExceptionHandler (PEXCEPTION_POINTERS exceptionInfo);
diff --git a/Source/OBSCapture.cpp b/Source/OBSCapture.cpp
index f2ef27f5..a70dddbe 100644
--- a/Source/OBSCapture.cpp
+++ b/Source/OBSCapture.cpp
@@ -312,6 +312,7 @@ void OBS::Start()
//-------------------------------------------------------------
bRunning = true;
+ UpdateNotificationAreaIcon();
if(sceneElement)
{
@@ -484,6 +485,7 @@ void OBS::Stop()
ReportStopStreamTrigger();
bRunning = false;
+ UpdateNotificationAreaIcon();
if(hMainThread)
{
OSTerminateThread(hMainThread, 20000);
diff --git a/Source/SettingsGeneral.cpp b/Source/SettingsGeneral.cpp
index 76b0d4fe..96af9dd9 100644
--- a/Source/SettingsGeneral.cpp
+++ b/Source/SettingsGeneral.cpp
@@ -79,6 +79,17 @@ void SettingsGeneral::DestroyPane()
void SettingsGeneral::ApplySettings()
{
+ //--------------------------------------------------
+
+ bool bShowNotificationAreaIcon = SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_GETCHECK, 0, 0) == BST_CHECKED;
+ AppConfig->SetInt(TEXT("General"), TEXT("ShowNotificationAreaIcon"), bShowNotificationAreaIcon);
+ if (bShowNotificationAreaIcon)
+ App->ShowNotificationAreaIcon();
+ else
+ App->HideNotificationAreaIcon();
+
+ bool bMinimizeToNotificationArea = SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_GETCHECK, 0, 0) == BST_CHECKED;
+ AppConfig->SetInt(TEXT("General"), TEXT("MinimizeToNotificationArea"), bMinimizeToNotificationArea);
}
void SettingsGeneral::CancelSettings()
@@ -145,6 +156,14 @@ INT_PTR SettingsGeneral::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
//----------------------------------------------
+ bool bShowNotificationAreaIcon = AppConfig->GetInt(TEXT("General"), TEXT("ShowNotificationAreaIcon"), 0) != 0;
+ SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_SETCHECK, bShowNotificationAreaIcon ? BST_CHECKED : BST_UNCHECKED, 0);
+
+ bool bMinimizeToNotificationArea = AppConfig->GetInt(TEXT("General"), TEXT("MinimizeToNotificationArea"), 0) != 0;
+ SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_SETCHECK, bMinimizeToNotificationArea ? BST_CHECKED : BST_UNCHECKED, 0);
+
+ //----------------------------------------------
+
SetChangedSettings(false);
return TRUE;
}
@@ -322,6 +341,22 @@ INT_PTR SettingsGeneral::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
break;
}
+
+ case IDC_NOTIFICATIONICON:
+ if (SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_GETCHECK, 0, 0) == BST_UNCHECKED)
+ {
+ SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_SETCHECK, BST_UNCHECKED, 0);
+ }
+ SetChangedSettings(true);
+ break;
+
+ case IDC_MINIZENOTIFICATION:
+ if (SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_GETCHECK, 0, 0) == BST_CHECKED)
+ {
+ SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_SETCHECK, BST_CHECKED, 0);
+ }
+ SetChangedSettings(true);
+ break;
}
}
diff --git a/Source/WindowStuff.cpp b/Source/WindowStuff.cpp
index 604891c4..45b1dd8c 100644
--- a/Source/WindowStuff.cpp
+++ b/Source/WindowStuff.cpp
@@ -2484,6 +2484,10 @@ LRESULT CALLBACK OBS::OBSProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
if(!App->bDragResize)
App->bSizeChanging = false;
}
+ else if (wParam == SIZE_MINIMIZED && AppConfig->GetInt(TEXT("General"), TEXT("MinimizeToNotificationArea"), 0) != 0)
+ {
+ ShowWindow(hwnd, SW_HIDE);
+ }
break;
}
@@ -2537,11 +2541,44 @@ LRESULT CALLBACK OBS::OBSProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
App->SetStatusBarData();
break;
+ case OBS_NOTIFICATIONAREA:
+ switch (lParam) {
+ case WM_LBUTTONUP:
+ {
+ bool bMinimizeToNotificationArea = AppConfig->GetInt(TEXT("General"), TEXT("MinimizeToNotificationArea"), 0) != 0;
+ if (bMinimizeToNotificationArea)
+ {
+ if (IsWindowVisible(hwnd))
+ {
+ ShowWindow(hwnd, SW_MINIMIZE);
+ ShowWindow(hwnd, SW_HIDE);
+ }
+ else
+ {
+ ShowWindow(hwnd, SW_SHOW);
+ ShowWindow(hwnd, SW_RESTORE);
+ }
+ }
+ else
+ {
+ if (IsIconic(hwnd))
+ ShowWindow(hwnd, SW_RESTORE);
+ else
+ ShowWindow(hwnd, SW_MINIMIZE);
+ }
+ }
+ }
+ break;
+
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
+ if (message == App->wmExplorerRestarted)
+ {
+ App->UpdateNotificationAreaIcon();
+ }
return DefWindowProc(hwnd, message, wParam, lParam);
}
diff --git a/resource.h b/resource.h
index df71bacb..2bfdb1b9 100644
--- a/resource.h
+++ b/resource.h
@@ -31,6 +31,7 @@
#define IDD_BUILDINGMP4 137
#define IDD_CONFIGURETEXTSOURCE 139
#define IDD_ENDINGDELAY 140
+#define IDI_ICON2 142
#define IDC_SETTINGSLIST 1006
#define IDC_SUBDIALOG 1007
#define IDC_MODE 1008
@@ -84,6 +85,7 @@
#define IDC_OPACITY 1041
#define IDC_USETEXTEXTENTS 1041
#define IDC_CUSTOMBUFFER 1041
+#define IDC_NOTIFICATIONICON 1041
#define IDC_SERVEREDIT 1042
#define IDC_USESENDBUFFER 1042
#define IDC_FORCEMONO 1042
@@ -194,6 +196,7 @@
#define IDC_CAPTURELAYERED 1099
#define IDC_USEOUTLINE 1099
#define IDC_LOWLATENCYMODE 1099
+#define IDC_MINIZENOTIFICATION 1099
#define IDC_TIMER1 1100
#define IDC_CAPTURERAM 1100
#define IDC_COMPATIBILITYMODE 1100
@@ -283,7 +286,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 141
+#define _APS_NEXT_RESOURCE_VALUE 143
#define _APS_NEXT_COMMAND_VALUE 40051
#define _APS_NEXT_CONTROL_VALUE 1157
#define _APS_NEXT_SYMED_VALUE 101
diff --git a/rundir/locale/en.txt b/rundir/locale/en.txt
index 4ab698f2..e8f19bdd 100644
--- a/rundir/locale/en.txt
+++ b/rundir/locale/en.txt
@@ -169,6 +169,8 @@ Settings.General.ConfirmDelete "Are you sure you wish to remove the profile '$1
Settings.General.InvalidName "Profile names cannot use the following characters:\r\n\\ / : * ? \" < > |"
Settings.General.Language "Language:"
Settings.General.Profile "Setting Profile:"
+Settings.General.Notification "Notification Area Icon"
+Settings.General.NotificationMinimize "Minimize to Notification Area"
Settings.General.Restart "Changing the language will require restarting OBS.\r\n\r\n..Though I suppose if you're changing the language you can't understand this"
Settings.Publish.AutoReconnect "Auto-Reconnect:"
diff --git a/ui/test2/recording.ico b/ui/test2/recording.ico
new file mode 100644
index 00000000..a498debb
Binary files /dev/null and b/ui/test2/recording.ico differ