Xamarin Forms for Mac runModalForWindow doesn't starting window as modal - cocoa

In my Xamarin Forms for Mac I have 2 windows:
A - main window
B - window that I want to open as modal.
Window B I opening using function RunModalForWindow.
Problem is that window B opening as common window and when I click on main window A the modal loses focus and goes out of the foreground.
How I can fix this problem?
Here is my code how I open my modal window:
this.window = new NSWindow(this.windowRect, NSWindowStyle.Closable, NSBackingStore.Buffered, false)
{
Title = "Pick install path",
TitleVisibility = NSWindowTitleVisibility.Hidden,
};
PickInstallPath pickInstallPath = new();
this.window.ContentViewController = pickInstallPath.CreateViewController();
this.window.ContentViewController.PreferredContentSize = this.windowRect.Size;
NSApplication.SharedApplication.RunModalForWindow(this.window);

Related

How to make Qt app visible on top on all screens?

How can I make a Qt window (keyboard launcher) show up on all spaces like e.g. Spotlight or iterm2 hotkey window.
I need to achieve the following: The launcher window has to be able to show up on every screen, even full screen apps, no dock item, not window switcher item, no main menu, this should work without any further implications (see below). Nice to have would be if the settings window would be still a regular window.
I tried to use qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "1"); but using this the window accepts no keyboard input anymore. I also tried
WId windowObject = this->winId();
objc_object * nsviewObject = reinterpret_cast<objc_object *>(windowObject);
objc_object * nsWindowObject = ((objc_object* (*)(id, SEL))objc_msgSend)(nsviewObject, sel_registerName("window"));
int NSWindowCollectionBehaviorMoveToActiveSpace = 1 << 1;
int NSWindowCollectionBehaviorTransient = 1 << 3;
int NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8;
int total = NSWindowCollectionBehaviorMoveToActiveSpace
|NSWindowCollectionBehaviorTransient
| NSWindowCollectionBehaviorFullScreenAuxiliary;
((objc_object* (*)(id, SEL, int))objc_msgSend)(nsWindowObject, sel_registerName("setCollectionBehavior:"), total);
but this way the window does not show over fullscreen apps and also has still a dock item and main menu.

PyQt5 control windows

In the above imange the background window is the main window of the screen. Then follows one Form that opens from the menu of the Main Window
and at the top you can see a QMessageBox like this:
box = QMessageBox()
box.setIcon(QMessageBox.Question)
box.setWindowTitle('Αποθήκευση αλλαγών')
box.setText('Θέλετε να αποθηκεύσετε τις αλλαγές σας;')
box.setStandardButtons(QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel)
buttonY = box.button(QMessageBox.Yes)
buttonY.setText('Ναι')
buttonN = box.button(QMessageBox.No)
buttonN.setText('Οχι')
buttonC = box.button(QMessageBox.Cancel)
buttonC.setText('Ακύρωση')
box.exec_()
if box.clickedButton() == buttonY:
self.save_and_close(True)
self.main_self.manage_microphone_window_is_open = False
event.accept()
elif box.clickedButton() == buttonN:
self.main_self.manage_microphone_window_is_open = False
event.accept()
elif box.clickedButton() == buttonC:
event.ignore()
I want in the bottom the Windows (bottom bottom there that start menu of windows and clock are) to show only one program.
Any ideas?
With the help of musicmante i did the following:
I change Form Window to QDialog and set MainWindow as parent
I set a parent to box: box = QMessageBox(dlg)
Note than in step 1 when you copy paste the QWidgets from Form to new Dialog (in QtDesigner), you may change the title of window the icon of window the style of the window and perhaps any other window settings.

UWP app with multiple views with different sizes

I have a UWP app. I want to be ale to create new windows from the app, but any subsequent window needs to be a specific smaller size compared to the main window. I don't do anything with regards to sizing the main window and let the OS take care of sizing it for me.
I bring up a new window like this:
auto window = CoreApplication::CreateNewView();
window->show();
void NewWindow::show() {
auto currView = ApplicationView::GetForCurrentView();
currView->PreferredLaunchViewSize =
Windows::Foundation::Size(float(options.width), float(options.height));
currView->PreferredLaunchWindowingMode = ApplicationViewWindowingMode::PreferredLaunchViewSize;
currView->SetPreferredMinSize(Size(20,20));
Xaml::Window::Current->Activate();
ApplicationViewSwitcher::TryShowAsStandaloneAsync(
window_->id(),
ViewSizePreference::Default,
window_->parentId(),
ViewSizePreference::Default);
}
When the main window comes up, it comes up just fine. When I click on a button which gets to this function, the new window comes up in the same size as the main window. I reopen the app, but now the main window shows up in the size I wanted the new window to show up in. Then clicking the button to bring up the new window brings up the new window in the size I wanted it in. So I am a bit confused. Am I setting the sizes the right way? Is there anything else glaringly wrong here?
As # Raymond Chen said, PreferredLaunchViewSize set the size when the app launches, it will change the size of your main window. And you can use ApplicationView.TryResizeView method to set the size of new window.
For example:
auto parentView = ApplicationView::GetForCurrentView();
auto newView = CoreApplication::CreateNewView();
newView->Dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
ref new Windows::UI::Core::DispatchedHandler([this,parentView]()
{
int newViewId = 0;
Windows::UI::Xaml::Controls::Frame^ rootFrame = ref new Windows::UI::Xaml::Controls::Frame();
rootFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(MainPage::typeid), nullptr);
Window::Current->Content = rootFrame;
// You have to activate the window in order to show it later.
Window::Current->Activate();
newViewId = ApplicationView::GetForCurrentView()->Id;
IAsyncOperation<bool>^ mytask = ApplicationViewSwitcher::TryShowAsStandaloneAsync(newViewId);
auto deviceEnumTask = concurrency::create_task(mytask);
deviceEnumTask.then([this](bool res)
{
// set the size of new window
ApplicationView::GetForCurrentView()->TryResizeView(Size(600, 320));
});
}));

Dialog window positioning

I'm creating a small non-modal dialog in TornadoFX like this:
find<Grib>(scope).apply { openModal(block = true,
owner = FX.primaryStage,
stageStyle = StageStyle.UTILITY,
modality = Modality.NONE) }
How do I go about setting (and retrieving) it's window position for later? That is, I have a preferences object for the window location and I want to update it so that the next time the user opens the window, it opens in the same place they last closed it.
I was able to mostly solve my problem by digging through some of the TornadoFX source code.
I added this to my init{} function:
Platform.runLater {
root.scene.window.x = Main.preferences.getDouble(GRIB_WINDOW_X, 400.0)
root.scene.window.y = Main.preferences.getDouble(GRIB_WINDOW_Y, 400.0)
}
And then adding this to my close() function:
Main.preferences.putDouble(GRIB_WINDOW_X, root.scene.window.x)
Main.preferences.putDouble(GRIB_WINDOW_Y, root.scene.window.y)
This "mostly" solves the problem in that it does save/restore the window position, however the window flickers when it is created as it moves from some default position to the newly set position.

Mac OS X Native Menu - How to destroy and access via dockSupport.dockMenu

I create and add an item to Mac OS X native menu. I add the menu to a window.
If I modify the menu item in this window it also changes it in the native menu. So if I do Services.wm.getMostRecentWindow('navigator:browser').myMacMenuItem.setAttribute('label','CHANGED') it will change the label the DOM of that window and consequently change the DOM in the Mac native menu.
However after this window closes I can't access the dom element anymore but the item persists in the dock. Is it possible to get the dom and modify by doing like: dockSupport.dockMenu.SOMETHING.
So I was wondering:
1. How to access the DOM of the menu via dockSupport.dockMenu.SOMETHING.childNodes[0].label = 'CHANGED';
2. How to destroy this, there is a dockSupport.dockMenu.init but no uninit
var dockSupport = Cc['#mozilla.org/widget/macdocksupport;1'].getService(Ci.nsIMacDockSupport);
console.log('dockSupport:', dockSupport);
var win = Services.wm.getMostRecentWindow('navigator:browser');
var macMenu = win.document.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'menupopup');
macMenu.setAttribute('id', 'myMacMenu');
var macMenuItem = win.document.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'menuitem');
macMenuItem.setAttribute('label', 'Show Most Recent Window');
macMenuItem.setAttribute('id', 'myMacMenuItem');
macMenuItem.addEventListener('command', function(){
var dockSupport = Cc['#mozilla.org/widget/macdocksupport;1'].getService(Ci.nsIMacDockSupport);
dockSupport.activateApplication(true);
Services.wm.getMostRecentWindow(null).focus()
})
macMenu.appendChild(macMenuItem);
var mainPopupSet = win.document.getElementById('mainPopupSet');
mainPopupSet.appendChild(macMenu);
let dockMenuElement = macMenu; //document.getElementById("menu_mac_dockmenu");66
let nativeMenu = Cc["#mozilla.org/widget/standalonenativemenu;1"].createInstance(Ci.nsIStandaloneNativeMenu);
console.log('dockMenuElement:', dockMenuElement);
nativeMenu.init(dockMenuElement);
dockSupport.dockMenu = nativeMenu;
it looks like this:

Resources