[Solved] Cannot get the desktop window

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
hika
Posts: 39
Joined: Tue Apr 17, 2018 12:53 am

[Solved] Cannot get the desktop window

Post by hika »

I can either create a desktop object or a toolkit object, but if I try to get the desktop window, I get None as a result. What is going wrong?

Code: Select all

context = uno.getComponentContext()
smgr = context.ServiceManager
desktop = smgr.createInstanceWithContext('com.sun.star.frame.Desktop', context)
desktopwindow = desktop.getContainerWindow()

Code: Select all

context = uno.getComponentContext()
smgr = context.ServiceManager
toolkit = smgr.createInstance('com.sun.star.awt.Toolkit')
desktopwindow = toolkit.getDesktopWindow()
I tried both in openoffice and in libreoffice. Both with and without a document open.

Hika
Last edited by hika on Wed May 23, 2018 8:33 pm, edited 1 time in total.
openoffice 4.1.2/4.1.4 and libreoffice 5.4.4.2/5.4.5.1 both on Gentoo and on Windows
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: Cannot get the desktop window

Post by hubert lambert »

Hi,

Afaik, the Desktop is a sort of abstract service that serves mainly as a frame containers. It has no window but every frame it contains does (as frames bind component to window).
When there is no opened document, the "current component" is the so-called start module, and you can access its component or container window throught its frame reference (no controller here) :

Code: Select all

    startmodule = XSCRIPTCONTEXT.getDocument()
    window = startmodule.Frame.ComponentWindow)
When a document is opened, it is most of the time loaded in the start module window, thus making a "desktop window" meaningless.

Regards.
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
hika
Posts: 39
Joined: Tue Apr 17, 2018 12:53 am

Re: Cannot get the desktop window

Post by hika »

I follow your reasoning and it sounds logical. Does this mean that "toolkit.getDesktopWindow()" is an old relic? Still there but no longer doing anything.

I was looking, because if I build a dialog embedded in a frame/window set: "unocomponent.createPeer(toolkit, None)" gives an error "unsatisfied query for interface of type com.sun.star.XView". Setting the peer to its own window works, but subsequently executing the dialog (through the XDialog interface in the window, executing it in the dialog no longer works) does not properly make it modal as it is modal to itself.
I will see if I can use your suggestion as a peer and if that will properly make it modal.

Hika
openoffice 4.1.2/4.1.4 and libreoffice 5.4.4.2/5.4.5.1 both on Gentoo and on Windows
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: Cannot get the desktop window

Post by hubert lambert »

hika wrote:Does this mean that "toolkit.getDesktopWindow()" is an old relic? Still there but no longer doing anything.
You should be right, as the Dev's Guide states that:
The name of this service originates at StarOffice 5.x, where all document windows were embedded into a common application window that was occupied by the StarOffice desktop, mirroring the Windows desktop. The root frame of this hierarchy was called the desktop frame. The name of this service and the interface name com.sun.star.frame.XDesktop were kept for compatibility reasons.
hika wrote:I was looking, because if I build a dialog embedded in a frame/window set: "unocomponent.createPeer(toolkit, None)" gives an error "unsatisfied query for interface of type com.sun.star.XView". Setting the peer to its own window works, but subsequently executing the dialog (through the XDialog interface in the window, executing it in the dialog no longer works) does not properly make it modal as it is modal to itself.
I'm not sure to fully understand. If you're not sure about the parent window, you can always pass the current frame component window:

Code: Select all

unocomponent.createPeer(toolkit, desktop.CurrentFrame.ComponentWindow)
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
hika
Posts: 39
Joined: Tue Apr 17, 2018 12:53 am

Re: Cannot get the desktop window

Post by hika »

It starts, but it breaks the binding between the dialog and its window/frame. So I guess that, if you want to embed a dialog in a window/frame set, setting that window as peer is mandatory.

What I mean by it not being properly modal is that executing it does not, as with a ordinary dialog, block access to the window from where you started it. I guess I have to find a way to make the dialog window a proper child of the executing window. It already, if you in its descriptor set the WindowServiceName to "modaldialog", takes over the com.sun.star.awt.XDialog(2) interfaces.
It is somewhere, but finding it ...

Hika
openoffice 4.1.2/4.1.4 and libreoffice 5.4.4.2/5.4.5.1 both on Gentoo and on Windows
hubert lambert
Posts: 145
Joined: Mon Jun 13, 2016 10:50 am

Re: Cannot get the desktop window

Post by hubert lambert »

It would be more convenient with a full example...
AOOo 4.1.2 on Win7 | LibreOffice on various Linux systems
hika
Posts: 39
Joined: Tue Apr 17, 2018 12:53 am

Re: Cannot get the desktop window

Post by hika »

It's a complex framework with a lot of subroutines, but this is the present __init__ for my unoForm class
It can create at present 5 types of dialogs/forms. From a classic dialog up to a window/frame set without a dialog model

Code: Select all

class UnoForm(UnoContainer, UnoTopFormListner, UnoBase):
    def __init__(self, ubase, name, **kwargs):
        UnoBase.__init__(self, ubase)
        self.initializing = True
        self.resizing = False
        self.args = kwargs
        self.log_settings = self.get_opt('log_settings', bool, False)
        self.log_object_tree = self.get_opt('log_object_tree', bool, False)
        self.log_size_tree = self.get_opt('log_size_tree', bool, False)
        self.log_listeners = self.get_opt('log_listeners', bool, False)
        self.form = self
        self.parent = self
        self.name = name
        self.datavalue = None
        self.properties = {'level': 0, 'form_defaults': {}, 'font': {}}
        self._init_properties(self, '--form_defaults--', '', 'form_defaults')
        self._init_properties(self, '', None, 'form')
        self._init_properties(self, '--possize--', self.uc_orientation.HORIZONTAL, 'form')
        self._init_properties(self, '--possize--', self.uc_orientation.VERTICAL, 'form')
        self.controls = {}
        self.data_controls = {}
        self.datavalues = {}
        self.tab_order = []
        self.containers = {self.name: self}
        self.datavalues['size_factor'] = Value(self, 'size_factor',
                    self.uno.uc_datatype.PERCENT,
                    self.properties['form_defaults']['size_factor'],
                    self.set_size_factor)
        if self.has_objmode('hasmodel'): # Create Model/Component
            self.implementation = 'UnoDialogControl'
            self.model = self.uno.get_service("awt.UnoControlDialogModel")
            self.model.Name = name
            self.model.Sizeable = True
            self.model.Closeable = True
            for k, v in self.get_opt('model', dict, {}).items():
                self.set_model_property(k, v)

            if self.has_objmode('hasframe'):
                self.model.Decoration = False

            self.properties['dialogmodel'] = 'UnoControlDialogModel'
            self.unocomponent = self.uno.get_service("awt.UnoControlDialog")
            self.unocomponent.setModel(self.model)
            #~ self.uno.list_capabilities(self.unocomponent)

        if self.has_objmode('haswindow'): # Create Window
            self.window = self.uno.get_toolkit().createWindow(self.get_descriptor())
            self.dialog = self.window
            if self.has_objmode('hasframe'): # Create Frame
                self.frame = self.uno.get_service("frame.Frame")
                self.frame.initialize(self.window)
                self.frame.setCreator(self.uno.desktop)
                self.frame.setName(name)
                self.uno.desktop.getFrames().append(self.frame)

        if self.has_objmode('hasmodel'): # Bind the Model
            if not self.has_objmode('hasframe'):
                self.dialog = self.unocomponent

            #~ self.uno.list_capabilities(self.uno.desktop.getCurrentFrame().getContainerWindow())
            #~ self.uno.list_capabilities(self.window)
            if not self.has_objmode('haswindow'): # to the Desktop
                self.unocomponent.createPeer(self.uno.get_toolkit(), None)

            elif self.has_objmode('ismodal'):
                self.unocomponent.createPeer(self.uno.get_toolkit(), self.window)

            else: # to the Window
                self.unocomponent.createPeer(self.uno.get_toolkit(), self.window)

            self.uno.list_capabilities(self.window)
            self.__init_component__(name)

        self.listeners = {'top': [], 'window': [], 'focus': [], 'key': [], 'mouse': []}
        self.set_visible(False)
        self._set_listener_proc()
        self.add_listener('all', self)
        self.load_datavalues(**self.get_opt('datavalues', (dict, Record), {}))
        if self._init_container(True):
            self.init_minsize()

        self.set_caption()
        self.set_font(**self.properties['font'])
        self.set_colors()
        self.set_properties()

    def get_descriptor(self):
        descriptor = self.uno.get_struct("awt.WindowDescriptor")
        #~ buttondialog, tabdialog, dialog, modaldialog, modelessdialog
        #~ framewindow, window, workwindow
        if self.has_objmode('ismodal'):
            descriptor.Type = self.ue_winclass.MODALTOP
            descriptor.WindowServiceName = "modaldialog"

        elif self.has_objmode('hasmodel'):
            descriptor.Type = self.ue_winclass.TOP
            descriptor.WindowServiceName = "modelessdialog"

        else:
            descriptor.Type = self.ue_winclass.TOP
            descriptor.WindowServiceName = "dialog"

        descriptor.ParentIndex = -1
        #~ descriptor.Parent = 0
        descriptor.WindowAttributes = self.properties['winattr']
        return descriptor

Maybe I must do something with the Parent in the window descriptor
openoffice 4.1.2/4.1.4 and libreoffice 5.4.4.2/5.4.5.1 both on Gentoo and on Windows
hika
Posts: 39
Joined: Tue Apr 17, 2018 12:53 am

Re: Cannot get the desktop window

Post by hika »

Yes! Setting descriptor.Parent = self.uno.desktop.getCurrentFrame().getContainerWindow() makes it truly modal. Only the minimize and maximize buttons then disappear while the dialog stays sizeable. Funny.
Obviously the descriptor.Parent for a window has a similar function as the peer for dialogs and controls.
openoffice 4.1.2/4.1.4 and libreoffice 5.4.4.2/5.4.5.1 both on Gentoo and on Windows
Post Reply