diff --git a/CMakeLists.txt b/CMakeLists.txt
index 592feb997efc2a2a9dd1151c6a1fd8fd54c680d9..fbf6bb7fa1682543e715886d048d6e66d65d949a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -175,6 +175,9 @@ if(UNIX AND NOT APPLE)
 	install(FILES "misc/minetest.desktop" DESTINATION "${XDG_APPS_DIR}")
 	install(FILES "misc/minetest.appdata.xml" DESTINATION "${APPDATADIR}")
 	install(FILES "misc/minetest.svg" DESTINATION "${ICONDIR}/hicolor/scalable/apps")
+	install(FILES "misc/minetest-xorg-icon-128.png"
+		DESTINATION "${ICONDIR}/hicolor/128x128/apps"
+		RENAME "minetest.png")
 endif()
 
 if(APPLE)
diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp
index aa3c2d5486db3633d4a47c0d4f8e129b8f5179c0..6145e3ddef379aa044fe56a08a5141748ba997dd 100644
--- a/src/client/clientlauncher.cpp
+++ b/src/client/clientlauncher.cpp
@@ -114,8 +114,7 @@ bool ClientLauncher::run(GameParams &game_params, const Settings &cmd_args)
 
 	porting::setXorgClassHint(video_driver->getExposedVideoData(), PROJECT_NAME_C);
 
-	porting::setXorgWindowIcon(device,
-		porting::path_share + "/misc/minetest-xorg-icon-128.png");
+	porting::setXorgWindowIcon(device);
 
 	/*
 		This changes the minimum allowed number of vertices in a VBO.
diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in
index 50f34a0b8b02853aba47c58363d26e49b6d99a4c..4b731020a945f3eb29559ec42f32bc8f6a1d71a9 100644
--- a/src/cmake_config.h.in
+++ b/src/cmake_config.h.in
@@ -14,6 +14,7 @@
 #define STATIC_SHAREDIR "@SHAREDIR@"
 #define STATIC_LOCALEDIR "@LOCALEDIR@"
 #define BUILD_TYPE "@CMAKE_BUILD_TYPE@"
+#define ICON_DIR "@ICONDIR@"
 #cmakedefine01 RUN_IN_PLACE
 #cmakedefine01 USE_GETTEXT
 #cmakedefine01 USE_CURL
diff --git a/src/porting.cpp b/src/porting.cpp
index acd0472329f12d33fe3ea306e8ecb0b4a2e92660..ae9114ac8c9f5b404ec1fcfbe41aa84235835b81 100644
--- a/src/porting.cpp
+++ b/src/porting.cpp
@@ -611,7 +611,24 @@ void setXorgClassHint(const video::SExposedVideoData &video_data,
 #endif
 }
 
-bool setXorgWindowIcon(IrrlichtDevice *device,
+bool setXorgWindowIcon(IrrlichtDevice *device)
+{
+#if RUN_IN_PLACE
+	return setXorgWindowIconFromPath(device,
+			path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png");
+#else
+	// We have semi-support for reading in-place data if we are
+	// compiled with RUN_IN_PLACE. Don't break with this and
+	// also try the path_share location.
+	return
+		setXorgWindowIconFromPath(device,
+			ICON_DIR "/hicolor/128x128/apps/" PROJECT_NAME ".png") ||
+		setXorgWindowIconFromPath(device,
+			path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png");
+#endif
+}
+
+bool setXorgWindowIconFromPath(IrrlichtDevice *device,
 	const std::string &icon_file)
 {
 #ifdef XORG_USED
diff --git a/src/porting.h b/src/porting.h
index 40f6b4dc3c39163673746963cc3f0cfb34eaf13b..f5c7efcb2df3d05df5e0287511d8e79ecb77dcad 100644
--- a/src/porting.h
+++ b/src/porting.h
@@ -367,7 +367,9 @@ inline const char *getPlatformName()
 void setXorgClassHint(const video::SExposedVideoData &video_data,
 	const std::string &name);
 
-bool setXorgWindowIcon(IrrlichtDevice *device,
+bool setXorgWindowIcon(IrrlichtDevice *device);
+
+bool setXorgWindowIconFromPath(IrrlichtDevice *device,
 	const std::string &icon_file);
 
 // This only needs to be called at the start of execution, since all future