diff --git a/CMakeLists.txt b/CMakeLists.txt
index 17af0ff4409ccbe0ffb4e2e23c95222903c02b6a..92d4d65fdcaec98f998fa273a8edce32dbfe667f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -308,6 +308,8 @@ endif()
 
 if(MSVC)
   set(WINDOWS_SYS_LIBS
+    windowsapp.lib
+    dwmapi.lib
     Shell32.lib
     Ole32.lib
     Advapi32.lib
diff --git a/daemon b/daemon
index e4fa5074cac04f7ba5f8e86b4ce371a3af6a0961..9d76cf5cc767e33ab06054bfa40ee45f671002bd 160000
--- a/daemon
+++ b/daemon
@@ -1 +1 @@
-Subproject commit e4fa5074cac04f7ba5f8e86b4ce371a3af6a0961
+Subproject commit 9d76cf5cc767e33ab06054bfa40ee45f671002bd
diff --git a/src/app/avadapter.cpp b/src/app/avadapter.cpp
index 35697e7878094abf47dd3aca0f275184f2c2188e..8e072d57a27ea957671133adc7a4c14639f5e42d 100644
--- a/src/app/avadapter.cpp
+++ b/src/app/avadapter.cpp
@@ -92,9 +92,15 @@ AvAdapter::shareEntireScreen(int screenNumber)
     if (!screen)
         return;
     QRect rect = screen->geometry();
+#ifdef WIN32
+    rect.moveRight(rect.right() - rect.left() + 1);
+    rect.moveLeft(0);
+    rect.moveBottom(rect.bottom() - rect.top() + 1);
+    rect.moveTop(0);
+#endif
 
     auto resource = lrcInstance_->getCurrentCallModel()
-                        ->getDisplay(getScreenNumber(),
+                        ->getDisplay(getScreenNumber(screenNumber),
                                      rect.x(),
                                      rect.y(),
                                      rect.width() * screen->devicePixelRatio(),
@@ -229,6 +235,7 @@ AvAdapter::shareWindow(const QString& windowId)
         ->addMedia(callId, resource, lrc::api::CallModel::MediaRequestType::SCREENSHARING);
 }
 
+#pragma optimize("", off)
 QString
 AvAdapter::getSharingResource(int screenId = -2, const QString& windowId = "")
 {
@@ -246,7 +253,14 @@ AvAdapter::getSharingResource(int screenId = -2, const QString& windowId = "")
             return "";
         QRect rect = screen->geometry();
 
-        return lrcInstance_->getCurrentCallModel()->getDisplay(getScreenNumber(),
+#ifdef WIN32
+        rect.moveRight(rect.right() - rect.left() + 1);
+        rect.moveLeft(0);
+        rect.moveBottom(rect.bottom() - rect.top() + 1);
+        rect.moveTop(0);
+#endif
+
+        return lrcInstance_->getCurrentCallModel()->getDisplay(screenId,
                                                                rect.x(),
                                                                rect.y(),
                                                                rect.width()
@@ -375,7 +389,7 @@ AvAdapter::hasCamera() const
 }
 
 int
-AvAdapter::getScreenNumber() const
+AvAdapter::getScreenNumber(int screenId) const
 {
     int display = 0;
 
@@ -389,6 +403,10 @@ AvAdapter::getScreenNumber() const
             display = list.at(0).toInt();
         }
     }
+#else
+#ifdef WIN32
+    display = screenId;
+#endif
 #endif
     return display;
 }
diff --git a/src/app/avadapter.h b/src/app/avadapter.h
index 2f115cf8a7b78789961ce2dde2720b8a916cbba0..c5ed95761c07378e0392c4f66333609e310ccd10 100644
--- a/src/app/avadapter.h
+++ b/src/app/avadapter.h
@@ -117,5 +117,5 @@ private:
     const QRect getAllScreensBoundingRect();
 
     // Get the screen number
-    int getScreenNumber() const;
+    int getScreenNumber(int screenId = 0) const;
 };
diff --git a/src/app/mainview/components/CallActionBar.qml b/src/app/mainview/components/CallActionBar.qml
index 62fff410d375b5eb8769080d84079f9aa30e45b4..3f9ed4d59523764bd1d27eb15ba7190f536d904f 100644
--- a/src/app/mainview/components/CallActionBar.qml
+++ b/src/app/mainview/components/CallActionBar.qml
@@ -121,12 +121,14 @@ Control {
                 Component.onCompleted: {
                     shareModel.append({"Name": JamiStrings.shareScreen,
                                        "IconSource": JamiResources.laptop_black_24dp_svg})
-                    if (Qt.platform.os == "linux") {
+                    if (Qt.platform.os.toString() !== "osx") {
                         shareModel.append({"Name": JamiStrings.shareWindow,
-                                           "IconSource" : JamiResources.window_black_24dp_svg})
+                                            "IconSource" : JamiResources.window_black_24dp_svg})
+                    }
+                    if (Qt.platform.os.toString() !== "windows") {  // temporarily disable for windows
+                        shareModel.append({"Name": JamiStrings.shareScreenArea,
+                                        "IconSource" : JamiResources.share_area_black_24dp_svg})
                     }
-                    shareModel.append({"Name": JamiStrings.shareScreenArea,
-                                       "IconSource" : JamiResources.share_area_black_24dp_svg})
                     shareModel.append({"Name": JamiStrings.shareFile,
                                        "IconSource" : JamiResources.file_black_24dp_svg})
                 }
diff --git a/src/app/mainview/components/CallViewContextMenu.qml b/src/app/mainview/components/CallViewContextMenu.qml
index 733178729a6be6c27cbd0346576af50f6dfc9bac..179df492f3632bb083adbb058d7e89f433d057f8 100644
--- a/src/app/mainview/components/CallViewContextMenu.qml
+++ b/src/app/mainview/components/CallViewContextMenu.qml
@@ -130,8 +130,7 @@ ContextMenuAutoLoader {
         GeneralMenuItem {
             id: shareWindow
 
-            canTrigger: Qt.platform.os === "linux"
-                        && CurrentAccount.videoEnabled_Video
+            canTrigger: CurrentAccount.videoEnabled_Video
                         && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
                         && !CurrentCall.isSIP
             itemName: JamiStrings.shareWindow
@@ -150,6 +149,7 @@ ContextMenuAutoLoader {
             canTrigger: CurrentAccount.videoEnabled_Video
                         && AvAdapter.currentRenderingDeviceType !== Video.DeviceType.DISPLAY
                         && !CurrentCall.isSIP
+                        && Qt.platform.os.toString() !== "windows" // temporarily disable for windows
             itemName: JamiStrings.shareScreenArea
             iconSource: JamiResources.share_area_black_24dp_svg
             onClicked: {
diff --git a/src/app/mainview/components/ScreenRubberBand.qml b/src/app/mainview/components/ScreenRubberBand.qml
index 1cebb882ad416452c87b3e13e32310071bf6d4db..700f368c5d9a5e08e6c6d15e48461b4e336ea9ec 100644
--- a/src/app/mainview/components/ScreenRubberBand.qml
+++ b/src/app/mainview/components/ScreenRubberBand.qml
@@ -32,18 +32,40 @@ Window {
     id: screenRubberBandWindow
 
     function setAllScreensGeo() {
-        var width = 0, height = 0
+        var width = 0, height = 0, x = 0, y = 0
         var screens = Qt.application.screens
         for (var i = 0; i < screens.length; ++i) {
-            width += screens[i].width
-            if (height < screens[i].height)
-                height = screens[i].height
+            var screenWidth = screens[i].width * screens[i].devicePixelRatio
+            var screenHeight = screens[i].height * screens[i].devicePixelRatio
+
+            if (screens[i].virtualX >= x + width)
+                width += screenWidth
+            else if (screens[i].virtualX + screenWidth <= x)
+                width += screenWidth
+            else if (screens[i].virtualX < x && screens[i].virtualX + screenWidth > x)
+                width += (x - screens[i].virtualX) * screens[i].devicePixelRatio
+            else if (screens[i].virtualX > x && screens[i].virtualX + screenWidth > x + width)
+                width += (screens[i].virtualX + screenWidth - x - width) * screens[i].devicePixelRatio
+
+            if (screens[i].virtualY >= y + height)
+                height += screenHeight
+            else if (screens[i].virtualY + screenHeight <= y)
+                height += screenHeight
+            else if (screens[i].virtualY < y && screens[i].virtualY + screenHeight > y)
+                height += (y - screens[i].virtualY) * screens[i].devicePixelRatio
+            else if (screens[i].virtualY > y && screens[i].virtualY + screenHeight > y + height)
+                height += (screens[i].virtualY + screenWidth - y - height) * screens[i].devicePixelRatio
+
+            if (screens[i].virtualY < y)
+                y = screens[i].virtualY
+            if (screens[i].virtualX < x)
+                x = screens[i].virtualX
         }
 
         screenRubberBandWindow.width = width
         screenRubberBandWindow.height = height
-        screenRubberBandWindow.x = 0
-        screenRubberBandWindow.y = 0
+        screenRubberBandWindow.x = x
+        screenRubberBandWindow.y = y
     }
 
     flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WA_TranslucentBackground
diff --git a/src/app/mainview/components/SelectScreen.qml b/src/app/mainview/components/SelectScreen.qml
index c3427120aaeefe3230cf8853dcaf39a9535cb3de..6488e3276c409010f473dbb09c3881c8c88922c7 100644
--- a/src/app/mainview/components/SelectScreen.qml
+++ b/src/app/mainview/components/SelectScreen.qml
@@ -65,7 +65,9 @@ Window {
         return screens.length
     }
 
-    onActiveChanged: {
+    onVisibleChanged: {
+        if (!visible)
+            return
         if (!active) {
             selectedScreenNumber = -1
             selectAllScreens = false
@@ -161,9 +163,7 @@ Window {
                             width: screenItem.width - 50
 
                             Component.onDestruction: {
-                                if (rendererId !== "" && rendererId !== currentPreview) {
-                                    VideoDevices.stopDevice(rendererId)
-                                }
+                                VideoDevices.stopDevice(rendererId)
                             }
                             Component.onCompleted: {
                                 if (visible) {
@@ -209,7 +209,7 @@ Window {
 
                     border.color: selectAllScreens ? JamiTheme.screenSelectionBorderColor : JamiTheme.tabbarBorderColor
 
-                    visible: !root.window && Qt.application.screens.length > 1
+                    visible: !root.window && Qt.application.screens.length > 1 && Qt.platform.os.toString() !== "windows"
 
                     Text {
                         id: screenNameAll
@@ -233,9 +233,7 @@ Window {
                         width: screenSelectionRectAll.width - 50
 
                         Component.onDestruction: {
-                            if (rendererId !== "" && rendererId !== currentPreview) {
-                                VideoDevices.stopDevice(rendererId)
-                            }
+                            VideoDevices.stopDevice(rendererId)
                         }
                         Component.onCompleted: {
                             if (visible) {
@@ -313,9 +311,7 @@ Window {
                             width: screenItem2.width - 50
 
                             Component.onDestruction: {
-                                if (rendererId !== "" && rendererId !== currentPreview) {
-                                    VideoDevices.stopDevice(rendererId)
-                                }
+                                VideoDevices.stopDevice(rendererId)
                             }
                             Component.onCompleted: {
                                 if (visible) {
diff --git a/src/libclient/avmodel.cpp b/src/libclient/avmodel.cpp
index 67ade3482b61a6ee1a6bb652643c87fc83c24db7..63aa950cec68c9798d9f785ff8a197d710e7a28d 100644
--- a/src/libclient/avmodel.cpp
+++ b/src/libclient/avmodel.cpp
@@ -53,6 +53,11 @@
 #if defined(Q_OS_UNIX) && !defined(__APPLE__)
 #include <xcb/xcb.h>
 #endif
+#ifdef WIN32
+#include "Windows.h"
+#include <tchar.h>
+#include <dwmapi.h>
+#endif
 
 namespace lrc {
 
@@ -540,6 +545,71 @@ AVModel::stopPreview(const QString& resource)
     VideoManager::instance().closeVideoInput(resource);
 }
 
+#ifdef WIN32
+BOOL
+IsAltTabWindow(HWND hwnd)
+{
+    LONG style = GetWindowLong(hwnd, GWL_STYLE);
+    if (!((style & WS_DISABLED) != WS_DISABLED)) {
+        return false;
+    }
+
+    DWORD cloaked = FALSE;
+    HRESULT hrTemp = DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, sizeof(cloaked));
+    if (SUCCEEDED(hrTemp) && cloaked == DWM_CLOAKED_SHELL) {
+        return false;
+    }
+
+    // Start at the root owner
+    HWND hwndWalk = GetAncestor(hwnd, GA_ROOTOWNER);
+
+    // See if we are the last active visible popup
+    HWND hwndTry;
+    while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry) {
+        if (IsWindowVisible(hwndTry))
+            break;
+        hwndWalk = hwndTry;
+    }
+    return hwndWalk == hwnd;
+}
+
+BOOL CALLBACK
+CbEnumAltTab(HWND hwnd, LPARAM lParam)
+{
+    // Do not show invisible windows
+    if (!IsWindowVisible(hwnd))
+        return TRUE;
+
+    // Alt-tab test as described by Raymond Chen
+    if (!IsAltTabWindow(hwnd))
+        return TRUE;
+
+    const size_t MAX_WINDOW_NAME = 256;
+    TCHAR windowName[MAX_WINDOW_NAME];
+    if (hwnd == GetShellWindow())
+        return TRUE;
+    else
+        GetWindowText(hwnd, windowName, MAX_WINDOW_NAME);
+
+    // Do not show windows that has no caption
+    if (0 == windowName[0])
+        return TRUE;
+
+    std::wstring msg = std::wstring(windowName);
+    auto name = QString::fromStdWString(msg);
+
+    QMap<QString, QVariant>* windowList = reinterpret_cast<QMap<QString, QVariant>*>(lParam);
+    auto keys = windowList->keys();
+    if (keys.indexOf(name) > 0) {
+        return FALSE;
+    } else {
+        windowList->insert(name, name);
+    }
+
+    return TRUE;
+}
+#endif
+
 #if defined(Q_OS_UNIX) && !defined(__APPLE__)
 static xcb_atom_t
 getAtom(xcb_connection_t* c, const std::string& atomName)
@@ -630,10 +700,19 @@ AVModel::getListWindows() const
             }
         }
     }
-    return ret;
-#else
-    return ret;
 #endif
+#ifdef WIN32
+    try {
+        auto newWindow = true;
+        LPARAM lParam = reinterpret_cast<LPARAM>(&ret);
+        while (newWindow) {
+            newWindow = EnumWindows(CbEnumAltTab, lParam);
+        }
+        auto finishedloop = true;
+    } catch (...) {
+    }
+ #endif
+    return ret;
 }
 
 void
diff --git a/src/libclient/callmodel.cpp b/src/libclient/callmodel.cpp
index c4e454ca403fea6c4760e772e1a6abae638057ee..17bbded66f97b6790ca7f94cf7358b1914bd682d 100644
--- a/src/libclient/callmodel.cpp
+++ b/src/libclient/callmodel.cpp
@@ -928,10 +928,20 @@ QString
 CallModel::getDisplay(const QString& windowId)
 {
     QString sep = libjami::Media::VideoProtocolPrefix::SEPARATOR;
-    return QString("%1%2:+0,0 window-id:%3")
+    QString ret{};
+#if (defined(Q_OS_UNIX) && !defined(__APPLE__))
+    ret = QString("%1%2:+0,0 window-id:%3")
         .arg(libjami::Media::VideoProtocolPrefix::DISPLAY)
         .arg(sep)
         .arg(windowId);
+#endif
+#ifdef WIN32
+    ret = QString("%1%2:+0,0 window-id:title=%3")
+        .arg(libjami::Media::VideoProtocolPrefix::DISPLAY)
+        .arg(sep)
+        .arg(windowId);
+#endif
+    return ret;
 }
 
 CallModelPimpl::CallModelPimpl(const CallModel& linked,
diff --git a/src/libclient/qtwrapper/videomanager_wrap.cpp b/src/libclient/qtwrapper/videomanager_wrap.cpp
index dd4ac4b678b92f01ad7412dcb94b0c1da9374ca2..f7889782cf01ce6101b86778209b50edd370ff03 100644
--- a/src/libclient/qtwrapper/videomanager_wrap.cpp
+++ b/src/libclient/qtwrapper/videomanager_wrap.cpp
@@ -30,15 +30,17 @@ VideoManagerInterface::VideoManagerInterface()
                                                                     int width,
                                                                     int height,
                                                                     bool isMixer) {
-               Q_EMIT decodingStarted(QString(id.c_str()),
-                                      QString(shmPath.c_str()),
+               Q_EMIT decodingStarted(QString::fromLatin1(QByteArray::fromStdString(id)),
+                                      QString::fromLatin1(QByteArray::fromStdString(shmPath)),
                                       width,
                                       height,
                                       isMixer);
            }),
            exportable_callback<VideoSignal::DecodingStopped>(
                [this](const std::string& id, const std::string& shmPath, bool isMixer) {
-                   Q_EMIT decodingStopped(QString(id.c_str()), QString(shmPath.c_str()), isMixer);
+                   Q_EMIT decodingStopped(QString::fromLatin1(QByteArray::fromStdString(id)),
+                                          QString::fromLatin1(QByteArray::fromStdString(shmPath)),
+                                          isMixer);
                })};
 #endif
 }
diff --git a/src/libclient/qtwrapper/videomanager_wrap.h b/src/libclient/qtwrapper/videomanager_wrap.h
index 24402596e85f8a927e7900989895c8109572e1da..4a2b68f4c1e32e60634879f03b81597fe21b5f1e 100644
--- a/src/libclient/qtwrapper/videomanager_wrap.h
+++ b/src/libclient/qtwrapper/videomanager_wrap.h
@@ -126,7 +126,7 @@ public Q_SLOTS: // METHODS
     QString openVideoInput(const QString& resource)
     {
 #ifdef ENABLE_VIDEO
-        return libjami::openVideoInput(resource.toLatin1().toStdString()).c_str();
+        return QByteArray::fromStdString(libjami::openVideoInput(resource.toLatin1().toStdString()));
 #endif
     }
 
@@ -150,7 +150,7 @@ public Q_SLOTS: // METHODS
     bool registerSinkTarget(const QString& sinkID, const libjami::SinkTarget& target)
     {
 #ifdef ENABLE_VIDEO
-        return libjami::registerSinkTarget(sinkID.toStdString(), target);
+        return libjami::registerSinkTarget(sinkID.toLatin1().toStdString(), target);
 #else
         Q_UNUSED(sinkID)
         Q_UNUSED(target)