diff --git a/src/app/MainApplicationWindow.qml b/src/app/MainApplicationWindow.qml index 943e2a7857bdc3dc16b0f13d8385b451fd377059..77dc3ce117c14cfebc2796b854a7310c8d61641b 100644 --- a/src/app/MainApplicationWindow.qml +++ b/src/app/MainApplicationWindow.qml @@ -19,19 +19,17 @@ import QtQuick.Window import QtQuick.Controls import QtQuick.Layouts import Qt5Compat.GraphicalEffects - import net.jami.Models 1.1 import net.jami.Adapters 1.1 import net.jami.Enums 1.1 import net.jami.Helpers 1.1 import net.jami.Constants 1.1 - import "mainview" import "mainview/components" import "wizardview" import "commoncomponents" - import QWindowKit +import QtQuick.Dialogs ApplicationWindow { id: appWindow @@ -63,7 +61,7 @@ ApplicationWindow { sourceComponent: GenericErrorsRow { id: genericError text: CurrentAccount.enabled ? JamiStrings.noNetworkConnectivity : JamiStrings.disabledAccount - height: visible? JamiTheme.qwkTitleBarHeight : 0 + height: visible ? JamiTheme.qwkTitleBarHeight : 0 } } @@ -87,9 +85,11 @@ ApplicationWindow { appContainer: fullscreenContainer } // Used to manage dynamic view loading and unloading. - property ViewManager viewManager: ViewManager {} + property ViewManager viewManager: ViewManager { + } // Used to manage the view stack and the current view. - property ViewCoordinator viewCoordinator: ViewCoordinator {} + property ViewCoordinator viewCoordinator: ViewCoordinator { + } // Used to prevent the window from being visible until the // window geometry has been restored and the view stack has @@ -199,7 +199,6 @@ ApplicationWindow { if (useFrameless) { windowAgent.setup(appWindow); } - mainViewLoader.active = true; // Dbus error handler for Linux. @@ -216,10 +215,14 @@ ApplicationWindow { "confirmLabel": JamiStrings.send, "rejectLabel": JamiStrings.dontSend, "textHAlign": Text.AlignLeft, - "textMaxWidth": 400, + "textMaxWidth": 400 + }); + dlg.accepted.connect(function () { + crashReporter.uploadLastReport(); + }); + dlg.rejected.connect(function () { + crashReporter.clearReports(); }); - dlg.accepted.connect(function () { crashReporter.uploadLastReport(); }); - dlg.rejected.connect(function () { crashReporter.clearReports(); }); } } @@ -293,7 +296,7 @@ ApplicationWindow { target: MainApplication function onAboutToQuit() { - cleanupMainView() + cleanupMainView(); } function onCloseRequested() { @@ -331,7 +334,7 @@ ApplicationWindow { }); } - function presentUpdateConfirmInstallDialog(switchToBeta=false) { + function presentUpdateConfirmInstallDialog(switchToBeta = false) { return viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", { "title": JamiStrings.updateDialogTitle, "infoText": switchToBeta ? JamiStrings.confirmBeta : JamiStrings.updateFound, @@ -382,7 +385,7 @@ ApplicationWindow { presentUpdateInfoDialog(JamiStrings.updateNotFound); } else { // Show a dialog describing that an update were found, and offering to install it. - presentUpdateConfirmInstallDialog() + presentUpdateConfirmInstallDialog(); } } @@ -393,4 +396,20 @@ ApplicationWindow { } onClosing: appWindow.close() + + // Capture the inputs to the main window while the File Dialog is open + // This is used to mitigate modality issues on Ubuntu 22.04 systems that use wayland. + Loader { + active: JamiQmlUtils.openFileDialogCount > 0 + sourceComponent: Popup { + modal: true + visible: true + closePolicy: Popup.NoAutoClose + width: appWindow.width + height: appWindow.height + background: Rectangle { + color: "#80808080" // Semi-transparent grey + } + } + } } diff --git a/src/app/ViewCoordinator.qml b/src/app/ViewCoordinator.qml index 78a9993ee817adc11d3f48c1616d1287b44eaf59..b26178814fbae30b37178e75f387a7c749b9994d 100644 --- a/src/app/ViewCoordinator.qml +++ b/src/app/ViewCoordinator.qml @@ -49,13 +49,13 @@ QtObject { // right side when not in RTL and should represent the main or content-type view. readonly property var visibleViews: { if (!currentView) - return [] + return []; if (isDualPane) { if (isInSinglePaneMode) - return [currentView.rightPaneItem] - return [currentView.leftPaneItem, currentView.rightPaneItem] + return [currentView.rightPaneItem]; + return [currentView.leftPaneItem, currentView.rightPaneItem]; } - return [currentView] + return [currentView]; } // Aggregate this info and expose it as a single string for convenience. // JSON indented by 2 spaces. @@ -64,12 +64,12 @@ QtObject { currentViewName: currentViewName, isDualPane: isDualPane, isInSinglePaneMode: isInSinglePaneMode, - visibleViews: visibleViews.map(function(view) { - return view && view.objectName || null; - }), - visibleViewWidths: visibleViews.map(function(view) { - return view && view.width || null; - }), + visibleViews: visibleViews.map(function (view) { + return view && view.objectName || null; + }), + visibleViewWidths: visibleViews.map(function (view) { + return view && view.width || null; + }) }; return JSON.stringify(info, null, 2); } @@ -96,9 +96,10 @@ QtObject { } // Create, present, and return a dialog object. - function presentDialog(parent, path, props = {}) { + function presentDialog(parent, path, props = {}, singleInstance = false) { // Open the dialog once the object is created - return viewManager.createUniqueView(path, parent, function (obj) { + let createFunc = singleInstance ? viewManager.createView : viewManager.createUniqueView; + return createFunc(path, parent, function (obj) { const doneCb = function () { viewManager.destroyView(path); }; diff --git a/src/app/commoncomponents/JamiFileDialog.qml b/src/app/commoncomponents/JamiFileDialog.qml index 85de226fa6088c2712975f97c769d90218ecd335..8a36368e85e90e747f8074cc436905084dd25e11 100644 --- a/src/app/commoncomponents/JamiFileDialog.qml +++ b/src/app/commoncomponents/JamiFileDialog.qml @@ -27,6 +27,14 @@ FileDialog { signal fileAccepted(string file) signal filesAccepted(var files) + Component.onCompleted: { + JamiQmlUtils.openFileDialogCount++; + } + + Component.onDestruction: { + JamiQmlUtils.openFileDialogCount--; + } + onAccepted: { switch (fileMode) { case FileDialog.OpenFile: diff --git a/src/app/mainview/components/ChatViewFooter.qml b/src/app/mainview/components/ChatViewFooter.qml index 2dac501fa6d7f474509ee39683ab6fed58e7a519..574ca39d74bf2656f8c6b91934381019705aa4e4 100644 --- a/src/app/mainview/components/ChatViewFooter.qml +++ b/src/app/mainview/components/ChatViewFooter.qml @@ -44,7 +44,7 @@ Rectangle { function updateMessageDraft() { // Store the current files that have not been sent, if any. Do the same for the message draft. var filePathDraft = []; - while(messageBar.fileContainer.filesToSendCount > 0) { + while (messageBar.fileContainer.filesToSendCount > 0) { var currentIndex = messageBar.fileContainer.filesToSendListModel.index(0, 0); var filePath = messageBar.fileContainer.filesToSendListModel.data(currentIndex, FilesToSend.FilePath); filePathDraft.push(filePath); @@ -66,7 +66,6 @@ Rectangle { messageBar.fileContainer.filesToSendListModel.addToPending(restoredContent["files"][i]); } } - } Connections { @@ -203,7 +202,7 @@ Rectangle { var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/JamiFileDialog.qml", { "fileMode": JamiFileDialog.OpenFiles, "nameFilters": [JamiStrings.allFiles] - }); + }, true); // is a single instance dlg.filesAccepted.connect(function (files) { setFilePathsToSend(files); }); diff --git a/src/app/net/jami/Constants/JamiQmlUtils.qml b/src/app/net/jami/Constants/JamiQmlUtils.qml index 25fafbf71b5d2e13549986f77c904a77cba839ba..7c387e058c0535b3103bd89535fbaf48d8881749 100644 --- a/src/app/net/jami/Constants/JamiQmlUtils.qml +++ b/src/app/net/jami/Constants/JamiQmlUtils.qml @@ -83,7 +83,8 @@ Item { function onDonationCampaignSettingsChanged() { // Changing any of the donation campaign settings will trigger a recompute // of the banner visibility. - updateIsDonationBannerVisible(); } + updateIsDonationBannerVisible(); + } } function updateIsDonationBannerVisible() { @@ -99,4 +100,7 @@ Item { const now = new Date(); return isVisible && now < endDate && now >= startDate; } + + // Track if a fileDialog is opened. Is int to account for eventual future features including multiple FileDialog + property int openFileDialogCount: 0 }