Working method for focusing widgets in panels and keyboard navigation for Tasks applet

Emdek emdeck at gmail.com
Fri Aug 21 09:50:26 CEST 2009


Hello

As we talked yesterday on IRC, on notmart request I'll now describe how  
works (to allow to discuss that on Tokamak) this quite simply hack,  
workaround, only sensible method (;-)) or name it whatever you like.


Some background

I've did Run Command applet in October (my first plasmoid and first Qt /  
KDE application ;-)) but i has two serious limitations in panels caused by  
two problems:
- not working menu and completion box (Qt bug still not fixed as of Qt 4.5  
and setting that flag to bypass QGraphicsView doesn't help either - I've  
found method that returns completion widget and others needed);
- and second, more important, not possible to focus widget when there are  
active windows on desktop.

Second is now fixed, idea come to me when Lechio (Daisy developer)  
described me workaround for problem with determining if window should be  
minimized when clicking on task in task managers located on desktop (yes,  
strange inspiration ;-)).
And then One idea come to me...


How it works

I've took code that finds parent view (similar to that from Corona, used  
in tool tip positioning) and if it finds valid one then i takes it WId and  
says KWindowSystem to force it activation.
In case of my applet it looks like this:


void RunCommandApplet::focusWidget()
{
     if (scene())
     {
         QGraphicsView *parentView = NULL;
         QGraphicsView *possibleParentView = NULL;

         foreach (QGraphicsView *view, scene()->views())
         {
             if (view->sceneRect().intersects(sceneBoundingRect()) ||  
view->sceneRect().contains(scenePos()))
             {
                 if (view->isActiveWindow())
                 {
                     parentView = view;

                     break;
                 }
                 else
                 {
                     possibleParentView = view;
                 }
             }
         }

         if (!parentView)
         {
             parentView = possibleParentView;
         }

         if (parentView)
         {
             KWindowSystem::forceActiveWindow(parentView->winId());
         }
     }

     raise();

     m_comboBox->setFocus();

     QTimer::singleShot(250, m_comboBox, SLOT(setFocus()));
}

That repeated setFocus() after delay is ugly but without it widget is not  
focused...


How it could be done for Plasma

I think that this could be used directly in Plasma, but not exposed (maybe  
in future there will be better solution, who knows).
It could be invoked internally when shortcut is activated (maybe there  
will be need to delay emitting activation signal to applet) and for mouse  
press on panel (event filter needed? widgets can block events before they  
will go to containment, right?), and maybe in other places, for example to  
focus panel to have possibility to switch between applets using tab (I'm  
not using keyboard navigation so I don't know how it should work in this  
case ;-)).
Maybe also for desktop, I'm not sure if widgets are focusable there when  
there are windows (for example not maximized).


I hope that it will help somehow and I've finally done something that will  
be really useful for all. :-P


By the way, I want to add keyboard navigation to Tasks applet (I've done  
it already for new version of my own task manager, Fancy Tasks) and I've  
some questions...

It should use only Tab and Shift + Tab?
Is there artwork for "focus" state?
Windows should be switched when task are (I've two modes, with pressed  
Ctrl it only switches focus and icon, I don't have only tasks ;-), could  
be activated by pressing Enter)?
Any other suggestions?

I'll prepare patch probably in next week (busy working on own projects  
now, sorry) and I want to do it myself.


Best regards,
Michał


More information about the Plasma-devel mailing list