From 41abdebaff0f767ccc739bd7429c96545b6c6e20 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Sat, 5 Feb 2022 22:34:58 +1000
Subject: Add Haiku support


diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index fee3472..1bbeda2 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -95,6 +95,15 @@ PRIVATE
     desktop-app::external_xxhash
 )
 
+if (HAIKU)
+	target_link_libraries(Telegram
+	PRIVATE
+		be
+		jpeg
+		translation
+	)
+endif()
+
 target_precompile_headers(Telegram PRIVATE ${src_loc}/stdafx.h)
 nice_target_sources(Telegram ${src_loc}
 PRIVATE
@@ -1235,6 +1244,16 @@ else()
     )
 endif()
 
+if (HAIKU)
+	remove_target_sources(Telegram ${src_loc}
+		platform/linux/notifications_manager_linux_dummy.cpp
+	)
+    nice_target_sources(Telegram ${src_loc}
+    PRIVATE
+		platform/linux/notifications_manager_haiku.cpp
+    )
+endif()
+
 if (DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
     remove_target_sources(Telegram ${src_loc}
         platform/linux/linux_wayland_integration.cpp
@@ -1378,7 +1397,7 @@ if (build_macstore)
 else()
     set(bundle_identifier "com.tdesktop.Telegram$<$<CONFIG:Debug>:Debug>")
     set(bundle_entitlements "Telegram.entitlements")
-    if (LINUX AND DESKTOP_APP_USE_PACKAGED)
+    if (LINUX AND NOT HAIKU AND DESKTOP_APP_USE_PACKAGED)
         set(output_name "telegram-desktop")
     else()
         set(output_name "Telegram")
diff --git a/Telegram/SourceFiles/calls/group/calls_group_menu.cpp b/Telegram/SourceFiles/calls/group/calls_group_menu.cpp
index 2f0c52d..63c550a 100644
--- a/Telegram/SourceFiles/calls/group/calls_group_menu.cpp
+++ b/Telegram/SourceFiles/calls/group/calls_group_menu.cpp
@@ -583,6 +583,7 @@ void FillMenu(
 			real->recordStartDateValue(),
 			handler));
 	}
+#ifndef Q_OS_HAIKU
 	if (addScreenCast) {
 		const auto sharing = call->isSharingScreen();
 		const auto toggle = [=] {
@@ -600,6 +601,7 @@ void FillMenu(
 				: tr::lng_group_call_screen_share_start(tr::now)),
 			toggle);
 	}
+#endif
 	menu->addAction(tr::lng_group_call_settings(tr::now), [=] {
 		if (const auto strong = weak.get()) {
 			showBox(Box(SettingsBox, strong));
diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp
index 1fd532c..504c62a 100644
--- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp
+++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp
@@ -1942,7 +1942,9 @@ void Panel::updateButtonsGeometry() {
 		const auto muteSize = _mute->innerSize().width() + 2 * addSkip;
 		const auto skip = st::groupCallButtonSkipSmall;
 		const auto fullWidth = (_video->width() + skip)
+#ifndef Q_OS_HAIKU
 			+ (_screenShare->width() + skip)
+#endif
 			+ (muteSize + skip)
 			+ (_settings ->width() + skip)
 			+ _hangup->width();
@@ -1953,9 +1955,13 @@ void Panel::updateButtonsGeometry() {
 			- membersWidth
 			- membersSkip
 			- fullWidth) / 2;
+#ifndef Q_OS_HAIKU
 		toggle(_screenShare, !hidden);
 		_screenShare->moveToLeft(left, buttonsTop);
 		left += _screenShare->width() + skip;
+#else
+		toggle(_screenShare, false);
+#endif
 		toggle(_video, !hidden);
 		_video->moveToLeft(left, buttonsTop);
 		left += _video->width() + skip;
diff --git a/Telegram/SourceFiles/core/core_settings.h b/Telegram/SourceFiles/core/core_settings.h
index f411bd4..5b09ce7 100644
--- a/Telegram/SourceFiles/core/core_settings.h
+++ b/Telegram/SourceFiles/core/core_settings.h
@@ -762,7 +762,7 @@ private:
 	rpl::variable<float64> _dialogsWidthRatio; // per-window
 	rpl::variable<int> _thirdColumnWidth = kDefaultThirdColumnWidth; // p-w
 	bool _notifyFromAll = true;
-	rpl::variable<bool> _nativeWindowFrame = false;
+	rpl::variable<bool> _nativeWindowFrame = true;
 	rpl::variable<std::optional<bool>> _systemDarkMode = std::nullopt;
 	rpl::variable<bool> _systemDarkModeEnabled = false;
 	WindowPosition _windowPosition; // per-window
diff --git a/Telegram/SourceFiles/core/sandbox.cpp b/Telegram/SourceFiles/core/sandbox.cpp
index 1641a58..3856c5e 100644
--- a/Telegram/SourceFiles/core/sandbox.cpp
+++ b/Telegram/SourceFiles/core/sandbox.cpp
@@ -261,9 +261,12 @@ Sandbox::~Sandbox() = default;
 
 bool Sandbox::event(QEvent *e) {
 	if (e->type() == QEvent::Quit && !Quitting()) {
-		Quit(QuitReason::QtQuitEvent);
-		e->ignore();
-		return false;
+		if (IsAppLaunched() && App().preventsQuit(QuitReason::QtQuitEvent)) {
+			e->ignore();
+			return false;
+		} else {
+			Quit(QuitReason::QtQuitEvent);
+		}
 	} else if (e->type() == QEvent::Close) {
 		Quit();
 	}
@@ -273,7 +276,7 @@ bool Sandbox::event(QEvent *e) {
 void Sandbox::socketConnected() {
 	LOG(("Socket connected, this is not the first application instance, sending show command..."));
 	_secondInstance = true;
-
+ 
 	QString commands;
 	const QStringList &lst(cSendPaths());
 	for (QStringList::const_iterator i = lst.cbegin(), e = lst.cend(); i != e; ++i) {
diff --git a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp
index 0437363..7685881 100644
--- a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp
@@ -12,6 +12,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "platform/linux/linux_xdp_open_with_dialog.h"
 #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#include <InterfaceKit.h>
+#include <StorageKit.h>
+#include <SupportKit.h>
+#include <MimeType.h>
+#include <Roster.h>
+#endif
+
 #include <QtCore/QProcess>
 #include <QtGui/QDesktopServices>
 
@@ -46,6 +55,23 @@ void UnsafeOpenEmailLink(const QString &email) {
 }
 
 bool UnsafeShowOpenWith(const QString &filepath) {
+#ifdef Q_OS_HAIKU	
+	BMessenger trackerMessenger("application/x-vnd.Be-TRAK");
+	if (trackerMessenger.IsValid()) {
+		update_mime_info(filepath.toUtf8().data(), false, true, false);
+
+		BEntry fileEntry(filepath.toUtf8().data());
+		entry_ref fileRef;
+		if (fileEntry.GetRef(&fileRef) == B_OK) {
+			BMessage openCommand(B_REFS_RECEIVED);
+			openCommand.AddRef("refs", &fileRef);
+			openCommand.AddInt32("launchUsingSelector", 0);
+			if (trackerMessenger.SendMessage(&openCommand) == B_OK)
+				return true;
+		}
+	}
+#endif
+
 #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 	if (internal::ShowXDPOpenWithDialog(filepath)) {
 		return true;
diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp
index efaf0a7..e6c20de 100644
--- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp
@@ -41,6 +41,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "base/platform/linux/base_linux_xcb_utilities.h"
 #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#endif
+
 #include <QtCore/QSize>
 #include <QtCore/QMimeData>
 #include <QtGui/QWindow>
@@ -493,11 +497,17 @@ bool MainWindow::hasTrayIcon() const {
 
 bool MainWindow::isActiveForTrayMenu() {
 	updateIsActive();
+#ifdef Q_OS_HAIKU
+	return isVisible();
+#else
 	return Platform::IsWayland() ? isVisible() : isActive();
+#endif
 }
 
 void MainWindow::psShowTrayMenu() {
+#ifndef Q_OS_HAIKU
 	_private->trayIconMenuXEmbed->popup(QCursor::pos());
+#endif
 }
 
 void MainWindow::psTrayMenuUpdated() {
@@ -511,6 +521,10 @@ void MainWindow::psSetupTrayIcon() {
 			Core::App().unreadBadge(),
 			Core::App().unreadBadgeMuted()));
 
+#ifdef Q_OS_HAIKU
+		trayIcon->setContextMenu(trayIconMenu);
+#endif
+
 		attachToTrayIcon(trayIcon);
 	}
 	updateIconCounters();
@@ -589,8 +603,10 @@ void MainWindow::updateIconCounters() {
 }
 
 void MainWindow::initTrayMenuHook() {
+#ifndef Q_OS_HAIKU
 	_private->trayIconMenuXEmbed.emplace(nullptr, trayIconMenu);
 	_private->trayIconMenuXEmbed->deleteOnHide(false);
+#endif
 }
 
 void MainWindow::createGlobalMenu() {
diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_haiku.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_haiku.cpp
new file mode 100644
index 0000000..8605b28
--- /dev/null
+++ b/Telegram/SourceFiles/platform/linux/notifications_manager_haiku.cpp
@@ -0,0 +1,268 @@
+/* 
+This file is part of Telegram Desktop for Haiku,
+
+For license and copyright information please follow this link:
+https://github.com/desktop-app/legal/blob/master/LEGAL
+
+Copyright (c) 2018-2021 Gerasim Troeglazov, 3dEyes@gmail.com
+*/
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "platform/linux/notifications_manager_linux.h"
+
+#include "window/notifications_utilities.h"
+#include "history/history.h"
+#include "lang/lang_keys.h"
+#include "core/application.h"
+#include "core/core_settings.h"
+#include "main/main_session.h"
+
+#define USE_HAIKU_UINT64
+#include "base/haiku_types.h"
+
+#include <AppKit.h>
+#include <SupportKit.h>
+#include <Notification.h>
+#include <InterfaceKit.h>
+#include <TranslationUtils.h>
+#include <OS.h>
+
+#define NOTIFY_MESSAGE_DEEP	16
+#define NOTIFY_PORT_NAME "tg_notify"
+#define NOTIFY_GATE_NAME "/bin/qnotify"
+#define NOTIFY_MESSAGE 'QNTF'
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+#include <QTimer>
+
+namespace Platform {
+namespace Notifications {
+
+bool Supported() {
+	return true;
+}
+
+void Finish() {
+}
+
+bool SkipAudio() {
+	return false;
+}
+
+bool SkipToast() {
+	return false;
+}
+
+bool SkipFlashBounce() {
+	return false;
+}
+
+bool SkipAudioForCustom() {
+	return false;
+}
+
+bool SkipToastForCustom() {
+	return false;
+}
+
+bool SkipFlashBounceForCustom() {
+	return false;
+}
+
+bool Enforced() {
+	return false;
+}
+
+bool ByDefault() {
+	return true;
+}
+
+void Create(Window::Notifications::System *system) {
+	if (Core::App().settings().nativeNotifications() && Supported()) {
+		auto result = std::make_unique<Manager>(system);
+		system->setManager(std::move(result));
+		return;
+	}
+	system->setManager(nullptr);
+}
+
+class Manager::Private : public QObject {
+
+public:
+	using Type = Window::Notifications::CachedUserpics::Type;
+	explicit Private(not_null<Manager*> manager, Type type);
+
+	void showNotification(
+		not_null<PeerData*> peer,
+		std::shared_ptr<Data::CloudImageView> &userpicView,
+		MsgId msgId,
+		const QString &title,
+		const QString &subtitle,
+		const QString &msg,
+		DisplayOptions options);
+
+	~Private();
+
+private:
+	void CheckNotificationAction();
+
+	QTimer *_checkNotificationTimer;
+	Window::Notifications::CachedUserpics _cachedUserpics;
+	const not_null<Manager*> _manager;
+	int32 _portId;
+};
+
+Manager::Private::Private(not_null<Manager*> manager, Type type)
+: _cachedUserpics(type)
+, _manager(manager) {
+	_portId = create_port(NOTIFY_MESSAGE_DEEP, NOTIFY_PORT_NAME);
+	_checkNotificationTimer = new QTimer(this);
+	connect(_checkNotificationTimer, &QTimer::timeout, this, &Manager::Private::CheckNotificationAction);
+	_checkNotificationTimer->start(250);
+}
+
+Manager::Private::~Private() {
+	delete _checkNotificationTimer;
+	if (_portId > 0)
+		delete_port(_portId);
+}
+
+void Manager::Private::CheckNotificationAction()
+{
+	ssize_t msgSize;
+
+	do {
+		msgSize = port_buffer_size_etc(_portId, B_RELATIVE_TIMEOUT, 0);
+	} while (msgSize == B_INTERRUPTED);
+
+	if (msgSize < 0)
+		return;
+
+	char* buffer = new(std::nothrow) char[msgSize];
+	if (!buffer)
+		return;
+
+	int32 code;
+	status_t result;
+	do {
+		result = read_port(_portId, &code, buffer, msgSize);
+	} while (result == B_INTERRUPTED);
+
+	BMessage message;
+
+	if (result < 0 || code != NOTIFY_MESSAGE) {
+		delete[] buffer;
+		return;
+	}
+	
+	if (message.Unflatten(buffer) == B_OK) {
+		uint64 sessionId = message.GetUInt64("session", 0);
+		uint64 peerId = message.GetUInt64("peer", 0);
+		int64 messageId = message.GetInt64("message", 0);
+
+		const auto key = FullPeer{
+			.sessionId = sessionId,
+			.peerId = PeerId(peerId)
+		};
+		const auto notificationId = NotificationId{ .full = key, .msgId = messageId };
+
+		crl::on_main(this, [=] {
+			_manager->notificationActivated(notificationId);
+		});
+	}
+	delete[] buffer;
+}
+
+void Manager::Private::showNotification(
+	not_null<PeerData*> peer,
+	std::shared_ptr<Data::CloudImageView> &userpicView,
+	MsgId msgId,
+	const QString &title,
+	const QString &subtitle,
+	const QString &msg,
+	DisplayOptions options) {
+	auto titleText = title;
+	auto subtitleText = subtitle;
+	auto msgText = msg;
+
+	const auto key = options.hideNameAndPhoto
+		? InMemoryKey()
+		: peer->userpicUniqueKey(userpicView);
+
+	auto userpicPath = _cachedUserpics.get(key, peer, userpicView);
+	BBitmap *icon = BTranslationUtils::GetBitmapFile(userpicPath.toUtf8().data());
+	QString args = QString(
+		"mode:port "
+		"target:tg_notify "
+		"session:uint64:%1 "
+		"peer:uint64:%2 "
+		"message:int64:%3")
+		.arg(peer->session().uniqueId()).arg(peer->id.value).arg(msgId.bare);
+	BNotification notify(B_INFORMATION_NOTIFICATION);
+	if (icon)
+		notify.SetIcon(icon);
+	notify.SetGroup("Telegram");
+	notify.SetTitle(titleText.toUtf8().data());
+	notify.SetContent(msgText.toUtf8().data());
+	entry_ref ref;
+	BEntry entry(NOTIFY_GATE_NAME);
+	entry.GetRef(&ref);
+	notify.SetOnClickFile(&ref);
+	notify.AddOnClickArg(BString(args.toUtf8().data()));
+	notify.Send();
+}
+
+Manager::Manager(not_null<Window::Notifications::System*> system)
+: NativeManager(system)
+, _private(std::make_unique<Private>(this, Private::Type::Rounded)) {
+}
+
+Manager::~Manager() = default;
+
+void Manager::doShowNativeNotification(
+		not_null<PeerData*> peer,
+		std::shared_ptr<Data::CloudImageView> &userpicView,
+		MsgId msgId,
+		const QString &title,
+		const QString &subtitle,
+		const QString &msg,
+		DisplayOptions options) {
+	_private->showNotification(
+		peer,
+		userpicView,
+		msgId,
+		title,
+		subtitle,
+		msg,
+		options);
+}
+
+void Manager::doClearAllFast() { }
+
+void Manager::doClearFromItem(not_null<HistoryItem*> item) { }
+
+void Manager::doClearFromHistory(not_null<History*> history) { }
+
+void Manager::doClearFromSession(not_null<Main::Session*> session) { }
+
+bool Manager::doSkipAudio() const {
+	return false;
+}
+
+bool Manager::doSkipToast() const {
+	return false;
+}
+
+bool Manager::doSkipFlashBounce() const {
+	return false;
+}
+
+} // namespace Notifications
+} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/linux/specific_linux.cpp b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
index 54eed49..7d1841d 100644
--- a/Telegram/SourceFiles/platform/linux/specific_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/specific_linux.cpp
@@ -35,6 +35,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "base/platform/linux/base_linux_xsettings.h"
 #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#endif
+
 #include <QtWidgets/QApplication>
 #include <QtWidgets/QStyle>
 #include <QtCore/QStandardPaths>
@@ -63,8 +67,36 @@ using UiWaylandIntegration = Ui::Platform::WaylandIntegration;
 using Platform::internal::WaylandIntegration;
 
 namespace Platform {
+
 namespace {
 
+#ifdef Q_OS_HAIKU
+void HaikuAutostart(bool start) {
+	const auto home = QDir::homePath();
+	if (home.isEmpty()) {
+		return;
+	}
+
+	QFile file(home + "/config/settings/boot/launch/telegram-desktop");
+	if (start) {
+		if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+			QTextStream out(&file);
+			out
+				<< "#!/bin/bash" << Qt::endl
+				<< "cd /system/apps" << Qt::endl
+				<< "./Telegram -autostart" << " &" << Qt::endl;
+			file.close();
+			file.setPermissions(file.permissions()
+				| QFileDevice::ExeOwner
+				| QFileDevice::ExeGroup
+				| QFileDevice::ExeOther);
+		}
+	} else {
+		file.remove();
+	}
+}
+#endif // Q_OS_HAIKU
+
 constexpr auto kDesktopFile = ":/misc/telegramdesktop.desktop"_cs;
 constexpr auto kIconName = "telegram"_cs;
 constexpr auto kDarkColorLimit = 192;
@@ -612,37 +644,6 @@ void psActivateProcess(uint64 pid) {
 //	objc_activateProgram();
 }
 
-namespace {
-
-#ifdef __HAIKU__
-void HaikuAutostart(bool start) {
-	const auto home = QDir::homePath();
-	if (home.isEmpty()) {
-		return;
-	}
-
-	QFile file(home + "/config/settings/boot/launch/telegram-desktop");
-	if (start) {
-		if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
-			QTextStream out(&file);
-			out
-				<< "#!/bin/bash" << Qt::endl
-				<< "cd /system/apps" << Qt::endl
-				<< "./Telegram -autostart" << " &" << Qt::endl;
-			file.close();
-			file.setPermissions(file.permissions()
-				| QFileDevice::ExeOwner
-				| QFileDevice::ExeGroup
-				| QFileDevice::ExeOther);
-		}
-	} else {
-		file.remove();
-	}
-}
-#endif // __HAIKU__
-
-} // namespace
-
 QString psAppDataPath() {
 	// Previously we used ~/.TelegramDesktop, so look there first.
 	// If we find data there, we should still use it.
@@ -656,8 +657,11 @@ QString psAppDataPath() {
 			return oldPath;
 		}
 	}
-
+#ifdef Q_OS_HAIKU
+	return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + '/';
+#else
 	return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + '/';
+#endif
 }
 
 void psDoCleanup() {
@@ -822,7 +826,7 @@ bool OpenSystemSettings(SystemSettingsType type) {
 				add("mate-volume-control");
 			}
 		}
-#ifdef __HAIKU__
+#ifdef Q_OS_HAIKU
 		add("Media");
 #endif // __ HAIKU__
 		add("pavucontrol-qt");
diff --git a/Telegram/ThirdParty/tgcalls/tgcalls/MediaManager.cpp b/Telegram/ThirdParty/tgcalls/tgcalls/MediaManager.cpp
index 057a9b5..68abe1e 100644
--- a/Telegram/ThirdParty/tgcalls/tgcalls/MediaManager.cpp
+++ b/Telegram/ThirdParty/tgcalls/tgcalls/MediaManager.cpp
@@ -967,7 +967,7 @@ void MediaManager::fillCallStats(CallStats &callStats) {
 }
 
 void MediaManager::setAudioInputDevice(std::string id) {
-#if defined(WEBRTC_IOS)
+#if defined(WEBRTC_IOS) || defined(__HAIKU__)
 #else
     SetAudioInputDeviceById(_audioDeviceModule.get(), id);
 #endif
diff --git a/Telegram/ThirdParty/tgcalls/tgcalls/group/GroupInstanceCustomImpl.cpp b/Telegram/ThirdParty/tgcalls/tgcalls/group/GroupInstanceCustomImpl.cpp
index 574260c..a78bf44 100644
--- a/Telegram/ThirdParty/tgcalls/tgcalls/group/GroupInstanceCustomImpl.cpp
+++ b/Telegram/ThirdParty/tgcalls/tgcalls/group/GroupInstanceCustomImpl.cpp
@@ -2782,7 +2782,7 @@ public:
     }
 
     void setAudioOutputDevice(const std::string &id) {
-#ifndef WEBRTC_IOS
+#if !defined(WEBRTC_IOS) && !defined(__HAIKU__)
         _threads->getWorkerThread()->Invoke<void>(RTC_FROM_HERE, [&] {
             SetAudioOutputDeviceById(_audioDeviceModule.get(), id);
         });
@@ -2790,7 +2790,7 @@ public:
     }
 
     void setAudioInputDevice(const std::string &id) {
-#ifndef WEBRTC_IOS
+#if !defined(WEBRTC_IOS) && !defined(__HAIKU__)
         _threads->getWorkerThread()->Invoke<void>(RTC_FROM_HERE, [&] {
             SetAudioInputDeviceById(_audioDeviceModule.get(), id);
         });
diff --git a/Telegram/lib_base/base/haiku_types.h b/Telegram/lib_base/base/haiku_types.h
new file mode 100644
index 0000000..3a57ce2
--- /dev/null
+++ b/Telegram/lib_base/base/haiku_types.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#ifdef Q_OS_HAIKU
+
+#define _SUPPORT_DEFS_H
+
+#ifdef __x86_64__
+#define int64 __haiku_int64
+#ifdef USE_HAIKU_UINT64
+#define uint64 __haiku_uint64
+#endif
+#else
+#define int32 __haiku_int32
+#define uint32 __haiku_uint32
+#endif
+
+typedef int32 status_t;
+typedef uint32 type_code;
+typedef uint32 perform_code;
+
+typedef int64 bigtime_t;
+typedef int64 nanotime_t;
+
+#endif
diff --git a/Telegram/lib_base/base/platform/linux/base_file_utilities_linux.cpp b/Telegram/lib_base/base/platform/linux/base_file_utilities_linux.cpp
index aa65e5e..60b761f 100644
--- a/Telegram/lib_base/base/platform/linux/base_file_utilities_linux.cpp
+++ b/Telegram/lib_base/base/platform/linux/base_file_utilities_linux.cpp
@@ -27,8 +27,58 @@
 #include <stdio.h>
 #include <fcntl.h>
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#include <AppKit.h>
+#include <StorageKit.h>
+#endif
+
 namespace base::Platform {
 namespace {
+	
+#ifdef Q_OS_HAIKU
+bool HaikuShowInFolder(const QString &filepath) {
+	try {
+		BMessenger trackerMessenger("application/x-vnd.Be-TRAK");
+		if (!trackerMessenger.IsValid())
+			return false;
+
+		BEntry fileEntry(filepath.toUtf8().data());
+		entry_ref fileRef;
+		if (fileEntry.GetRef(&fileRef) != B_OK)
+			return false;
+
+		if (!fileEntry.Exists())
+			return false;
+
+		BEntry folderEntry;
+		if (fileEntry.GetParent(&folderEntry) != B_OK)
+			return false;
+
+		entry_ref folderRef;
+		if (folderEntry.GetRef(&folderRef) != B_OK)
+			return false;
+
+		BMessage openCommand(B_REFS_RECEIVED);
+		openCommand.AddRef("refs", &folderRef);
+		node_ref fileNodeRef;
+		if (fileEntry.GetNodeRef(&fileNodeRef) == B_OK) {
+			openCommand.AddData("nodeRefToSelect", B_RAW_TYPE,
+				static_cast<void*>(&fileNodeRef), sizeof(node_ref));
+		}
+		if (trackerMessenger.SendMessage(&openCommand) == B_OK) {
+			snooze(300000);
+			BMessage selectCommand('Tsel');
+			selectCommand.AddRef("refs", &fileRef);
+			trackerMessenger.SendMessage(&selectCommand);
+			return true;
+		}
+	} catch (...) {
+	}
+
+	return false;
+}
+#endif
 
 #ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 bool PortalShowInFolder(const QString &filepath) {
@@ -152,6 +202,12 @@ bool ShowInFolder(const QString &filepath) {
 		return true;
 	}
 
+#ifdef Q_OS_HAIKU
+	if (HaikuShowInFolder(filepath)) {
+		return true;
+	}
+#endif
+
 	if (ProcessShowInFolder(filepath)) {
 		return true;
 	}
diff --git a/Telegram/lib_base/base/platform/linux/base_last_input_linux.cpp b/Telegram/lib_base/base/platform/linux/base_last_input_linux.cpp
index 033dcbd..bf7d541 100644
--- a/Telegram/lib_base/base/platform/linux/base_last_input_linux.cpp
+++ b/Telegram/lib_base/base/platform/linux/base_last_input_linux.cpp
@@ -24,6 +24,11 @@
 #include <xcb/screensaver.h>
 #endif // !DESKTOP_APP_DISABLE_X11_INTEGRATION
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#include <InterfaceDefs.h>
+#endif
+
 namespace base::Platform {
 namespace {
 
@@ -184,9 +189,23 @@ std::optional<crl::time> MutterDBusLastUserInputTime() {
 }
 #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 
+#ifdef Q_OS_HAIKU
+std::optional<crl::time> HaikuLastUserInputTime() {	
+	const auto idle = idle_time() / 1000;
+	return (crl::now() - static_cast<crl::time>(idle));
+}
+#endif
+
 } // namespace
 
 std::optional<crl::time> LastUserInputTime() {
+#ifdef Q_OS_HAIKU
+	const auto haikuResult = HaikuLastUserInputTime();
+	if (haikuResult.has_value()) {
+		return haikuResult;
+	}
+#endif
+
 #ifndef DESKTOP_APP_DISABLE_X11_INTEGRATION
 	if (::Platform::IsX11()) {
 		const auto xcbResult = XCBLastUserInputTime();
diff --git a/Telegram/lib_base/base/platform/linux/base_linux_wayland_integration_dummy.cpp b/Telegram/lib_base/base/platform/linux/base_linux_wayland_integration_dummy.cpp
index 4253274..65c28e2 100644
--- a/Telegram/lib_base/base/platform/linux/base_linux_wayland_integration_dummy.cpp
+++ b/Telegram/lib_base/base/platform/linux/base_linux_wayland_integration_dummy.cpp
@@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 #include "base/platform/base_platform_info.h"
 
-namespace Ui {
+namespace base {
 namespace Platform {
 
 struct WaylandIntegration::Private {
@@ -34,4 +34,4 @@ void WaylandIntegration::preventDisplaySleep(bool prevent, QWindow *window) {
 }
 
 } // namespace Platform
-} // namespace Ui
+} // namespace Base
diff --git a/Telegram/lib_base/base/platform/linux/base_power_save_blocker_linux.cpp b/Telegram/lib_base/base/platform/linux/base_power_save_blocker_linux.cpp
index 690752d..f7432eb 100644
--- a/Telegram/lib_base/base/platform/linux/base_power_save_blocker_linux.cpp
+++ b/Telegram/lib_base/base/platform/linux/base_power_save_blocker_linux.cpp
@@ -21,6 +21,10 @@
 #include <giomm.h>
 #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#endif
+
 #include <QtGui/QWindow>
 #include <private/qguiapplication_p.h>
 
diff --git a/Telegram/lib_base/base/platform/linux/base_url_scheme_linux.cpp b/Telegram/lib_base/base/platform/linux/base_url_scheme_linux.cpp
index 20aed5e..61d46fc 100644
--- a/Telegram/lib_base/base/platform/linux/base_url_scheme_linux.cpp
+++ b/Telegram/lib_base/base/platform/linux/base_url_scheme_linux.cpp
@@ -13,6 +13,10 @@
 #include "base/platform/linux/base_linux_glibmm_helper.h"
 #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#endif
+
 #include <QtCore/QFile>
 #include <QtCore/QProcess>
 #include <QtGui/QWindow>
diff --git a/Telegram/lib_ui/ui/platform/linux/ui_utility_linux.cpp b/Telegram/lib_ui/ui/platform/linux/ui_utility_linux.cpp
index f55ed32..6ec825d 100644
--- a/Telegram/lib_ui/ui/platform/linux/ui_utility_linux.cpp
+++ b/Telegram/lib_ui/ui/platform/linux/ui_utility_linux.cpp
@@ -618,7 +618,7 @@ TitleControls::Layout TitleControlsLayout() {
 	}
 #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION
 
-#ifdef __HAIKU__
+#ifdef Q_OS_HAIKU
 	return TitleControls::Layout{
 		.left = {
 			TitleControls::Control::Close,
@@ -628,7 +628,7 @@ TitleControls::Layout TitleControlsLayout() {
 			TitleControls::Control::Maximize,
 		}
 	};
-#else // __HAIKU__
+#else // Q_OS_HAIKU
 	return TitleControls::Layout{
 		.right = {
 			TitleControls::Control::Minimize,
@@ -636,7 +636,7 @@ TitleControls::Layout TitleControlsLayout() {
 			TitleControls::Control::Close,
 		}
 	};
-#endif // !__HAIKU__
+#endif // !Q_OS_HAIKU
 }
 
 } // namespace Platform
diff --git a/Telegram/lib_ui/ui/ui_utility.cpp b/Telegram/lib_ui/ui/ui_utility.cpp
index e66055d..e31d635 100644
--- a/Telegram/lib_ui/ui/ui_utility.cpp
+++ b/Telegram/lib_ui/ui/ui_utility.cpp
@@ -9,6 +9,10 @@
 #include "ui/platform/ui_platform_utility.h"
 #include "ui/style/style_core.h"
 
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#endif
+
 #include <QtWidgets/QApplication>
 #include <QtGui/QWindow>
 #include <QtGui/QtEvents>
diff --git a/Telegram/lib_webrtc/webrtc/details/webrtc_openal_adm.cpp b/Telegram/lib_webrtc/webrtc/details/webrtc_openal_adm.cpp
index 9955bd3..ca023c1 100644
--- a/Telegram/lib_webrtc/webrtc/details/webrtc_openal_adm.cpp
+++ b/Telegram/lib_webrtc/webrtc/details/webrtc_openal_adm.cpp
@@ -4,6 +4,11 @@
 // For license and copyright information please follow this link:
 // https://github.com/desktop-app/legal/blob/master/LEGAL
 //
+
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#endif
+
 #include "webrtc/details/webrtc_openal_adm.h"
 
 #include "base/timer.h"
diff --git a/Telegram/lib_webrtc/webrtc/webrtc_audio_input_tester.cpp b/Telegram/lib_webrtc/webrtc/webrtc_audio_input_tester.cpp
index 092b667..204e259 100644
--- a/Telegram/lib_webrtc/webrtc/webrtc_audio_input_tester.cpp
+++ b/Telegram/lib_webrtc/webrtc/webrtc_audio_input_tester.cpp
@@ -4,6 +4,11 @@
 // For license and copyright information please follow this link:
 // https://github.com/desktop-app/legal/blob/master/LEGAL
 //
+
+#ifdef Q_OS_HAIKU
+#include <base/haiku_types.h>
+#endif
+
 #include "webrtc/webrtc_audio_input_tester.h"
 
 #include "webrtc/webrtc_create_adm.h"
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 465f5f7..f2f13fc 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -5,7 +5,7 @@
 # https://github.com/desktop-app/legal/blob/master/LEGAL
 
 add_subdirectory(external)
-if (LINUX)
+if (LINUX AND NOT HAIKU)
     add_subdirectory(linux_jemalloc_helper)
 endif()
 if (LINUX AND NOT DESKTOP_APP_USE_PACKAGED)
diff --git a/cmake/external/CMakeLists.txt b/cmake/external/CMakeLists.txt
index 0922a66..3d08188 100644
--- a/cmake/external/CMakeLists.txt
+++ b/cmake/external/CMakeLists.txt
@@ -37,7 +37,7 @@ if (add_hunspell_library)
 	add_checked_subdirectory(hunspell)
 endif()
 add_checked_subdirectory(iconv)
-if (LINUX)
+if (LINUX AND NOT HAIKU)
     add_checked_subdirectory(jemalloc)
 endif()
 add_checked_subdirectory(jpeg)
diff --git a/cmake/options_linux.cmake b/cmake/options_linux.cmake
index a12feab..76efc15 100644
--- a/cmake/options_linux.cmake
+++ b/cmake/options_linux.cmake
@@ -62,12 +62,14 @@ if (DESKTOP_APP_SPECIAL_TARGET)
     target_link_options(common_options INTERFACE $<IF:$<CONFIG:Debug>,,-g -flto -fuse-linker-plugin>)
 endif()
 
+if (NOT HAIKU)
 target_link_libraries(common_options
 INTERFACE
     desktop-app::linux_jemalloc_helper
     $<TARGET_OBJECTS:desktop-app::linux_jemalloc_helper>
     ${CMAKE_DL_LIBS}
 )
+endif()
 
 if (DESKTOP_APP_USE_ALLOCATION_TRACER)
     target_link_options(common_options
-- 
2.30.2

