Results 1 to 2 of 2

Thread: Resize cursor doesn't change back (qx11embedcontainer in qmdisubwindow in qmdiarea)

  1. #1
    Join Date
    Jun 2012
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Resize cursor doesn't change back (qx11embedcontainer in qmdisubwindow in qmdiarea)

    Hi,

    I'm writing some kind of a window manager. Therefor I'm embedding windows
    within a QX11EmbedContainer in a QMdiSubWindow in a QMdiArea. That part
    is working fine.

    The problem is the resizing cursor, which doesn't change back into a normal
    pointer when moving it from the edge of a QMdiSubWindow to the center,
    where the QX11EmbedContainer is. When moving the cursor from the edge of
    the QMdiSubWindow to the QMdiArea, the resize cursor changes back to a
    normal pointer.

    I think QX11EmbedContainer eats some events meant for the
    QMdiSubWindow. So, the QMdiSubWindow doesn't notice when to reset the
    cursor. But, i haven't figured out how to deal with that.

    Here's a stripped down example showing the effect. You'll need to start an
    application (i.e. I tested with `evince`) and pass the window id as argument
    to the test application.

    Cpp Code:
    1. #include <QApplication>
    2. #include <QDebug>
    3. #include <QMdiArea>
    4. #include <QMdiSubWindow>
    5. #include <QObject>
    6. #include <QTimer>
    7. #include <QX11EmbedContainer>
    8.  
    9. class Container : public QX11EmbedContainer
    10. {
    11. Q_OBJECT
    12. public:
    13. Container(QMdiArea *_area, int client)
    14. :QX11EmbedContainer(),
    15. area(_area)
    16. {
    17. QObject::connect
    18. (this, SIGNAL(clientClosed()),
    19. SLOT(slot_client_closed()));
    20. QObject::connect
    21. (this, SIGNAL(clientIsEmbedded()),
    22. SLOT(slot_client_is_embedded()));
    23. QObject::connect
    24. (this, SIGNAL(error(QX11EmbedContainer::Error)),
    25. SLOT(slot_client_error(QX11EmbedContainer::Error)));
    26.  
    27. frame = new QMdiSubWindow();
    28. frame->setWidget(this);
    29.  
    30. embedClient(client);
    31. }
    32.  
    33. private:
    34. QMdiArea *area;
    35. QMdiSubWindow *frame;
    36. void exit(void) {QTimer::singleShot(250, qApp, SLOT(quit()));}
    37.  
    38. public slots:
    39. void slot_client_closed(void) {exit();}
    40. void slot_client_is_embedded(void)
    41. {
    42. area->addSubWindow(frame);
    43. frame->show();
    44. }
    45. void slot_client_error(QX11EmbedContainer::Error error)
    46. {
    47. qDebug() << "error #" << error;
    48. exit();
    49. }
    50. };
    51.  
    52. /* ugly hack to prevent: undefined reference to `vtable... */
    53. #include "main.moc"
    54.  
    55. int main(int argc, char *argv[])
    56. {
    57. QApplication *app = new QApplication(argc, argv);
    58.  
    59. if (app->arguments().count() != 2) {
    60. qFatal("Error - expected window id as argument");
    61. return 1;
    62. }
    63.  
    64. QMdiArea *area = new QMdiArea();
    65. area->show();
    66.  
    67. new Container(area, app->arguments()[1].toInt(0, 16));
    68.  
    69. return app->exec();
    70. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jun 2012
    Posts
    2
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Resize cursor doesn't change back (qx11embedcontainer in qmdisubwindow in qmdiare

    Just found a solution - raw XEvents:
    - register an event filter
    - search for an EnterNotify with a matching subwindow id
    - set the desired cursor

    cpp Code:
    1. #include <QApplication>
    2. #include <QDebug>
    3. #include <QMdiArea>
    4. #include <QMdiSubWindow>
    5. #include <QObject>
    6. #include <QTimer>
    7. #include <QX11EmbedContainer>
    8. #include <QX11Info>
    9.  
    10. #include <X11/cursorfont.h>
    11. #include <X11/Xlib.h>
    12.  
    13. class Container : public QX11EmbedContainer
    14. {
    15. Q_OBJECT
    16. public:
    17. Container(QMdiArea *_area, Window _client)
    18. :QX11EmbedContainer(),
    19. area(_area)
    20. {
    21. QObject::connect
    22. (this, SIGNAL(clientClosed()),
    23. SLOT(slot_client_closed()));
    24. QObject::connect
    25. (this, SIGNAL(clientIsEmbedded()),
    26. SLOT(slot_client_is_embedded()));
    27. QObject::connect
    28. (this, SIGNAL(error(QX11EmbedContainer::Error)),
    29. SLOT(slot_client_error(QX11EmbedContainer::Error)));
    30.  
    31. frame = new QMdiSubWindow();
    32. frame->setWidget(this);
    33.  
    34. embedClient(_client);
    35. }
    36.  
    37. private:
    38. QMdiArea *area;
    39. QMdiSubWindow *frame;
    40. void exit(void) {QTimer::singleShot(250, qApp, SLOT(quit()));}
    41.  
    42. public slots:
    43. void slot_client_closed(void) {exit();}
    44. void slot_client_is_embedded(void)
    45. {
    46. area->addSubWindow(frame);
    47. frame->show();
    48. }
    49. void slot_client_error(QX11EmbedContainer::Error error)
    50. {
    51. qDebug() << "error #" << error;
    52. exit();
    53. }
    54. };
    55.  
    56. class X11EventFilter
    57. {
    58. public:
    59. static bool x11_event_filter(void *msg, long *res)
    60. {
    61. XEvent *ev = reinterpret_cast<XEvent*>(msg);
    62. if (ev->xany.type != EnterNotify) return NULL;
    63.  
    64. if (X11EventFilter::client == ev->xcrossing.subwindow) {
    65. XDefineCursor
    66. (QX11Info::display(), X11EventFilter::client,
    67. XCreateFontCursor
    68. (QX11Info::display(), XC_left_ptr));
    69. }
    70.  
    71. return false;
    72. }
    73.  
    74. static Window client;
    75. };
    76. Window X11EventFilter::client = 0;
    77.  
    78. /* ugly hack to prevent: undefined reference to `vtable... */
    79. #include "main.moc"
    80.  
    81. int main(int argc, char *argv[])
    82. {
    83. QApplication *app = new QApplication(argc, argv);
    84.  
    85. if (app->arguments().count() != 2) {
    86. qFatal("Error - expected window id as argument");
    87. return 1;
    88. }
    89.  
    90. app->setEventFilter(X11EventFilter::x11_event_filter);
    91.  
    92. QMdiArea *area = new QMdiArea();
    93. area->show();
    94.  
    95. X11EventFilter::client = app->arguments()[1].toInt(0, 16);
    96. new Container(area, X11EventFilter::client);
    97.  
    98. return app->exec();
    99. }
    To copy to clipboard, switch view to plain text mode 

    Well, it works as I want. But, it doesn't look like the best solution to me.
    Any suggestions for improvements? A plain Qt solution?


    Added after 1 26 minutes:


    The solution with XDefineCursor() was not that perfect - as expected. Now, instead of
    using XDefineCursor(), I "find" and call unsetCursor() of the underlying QMdiSubWindow.

    If I don't report back. I haven't found any other issues with that solution.
    Last edited by bartsch; 28th June 2012 at 14:29.

Similar Threads

  1. Getting Cursor position within QMdiSubWindow
    By stevel in forum Qt Programming
    Replies: 1
    Last Post: 12th March 2012, 11:09
  2. QMdiArea + QWidget: no resize cursor
    By trallallero in forum Qt Programming
    Replies: 6
    Last Post: 6th March 2012, 12:59
  3. Wish to have a QMdiSubWindow window larger than the QMdiArea
    By zenzero-2001 in forum Qt Programming
    Replies: 2
    Last Post: 18th August 2010, 17:44
  4. Validator: force keeping cursor back in widget
    By antarctic in forum Qt Programming
    Replies: 1
    Last Post: 8th June 2009, 14:15
  5. QX11EmbedContainer into QMdiArea
    By peppino in forum Qt Programming
    Replies: 0
    Last Post: 25th September 2008, 17:12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.