pip resizing and moving

Dennis New <[email protected]>
Newsgroups gmane.comp.gnome.apps.gnomemeeting
Message-ID <[email protected]>
Here's a patch (against 4.0.1) to make the Picture-In-Picture (PIP)
resizable and moveable, by right-clicking in the window. It can be
moved to any of the four corners, depending on which quadrant you right
click. It resizes the width to the x-offset from the edge.

By the way, is everyone (linux users at least) able to get Fullscreen
video through the Call Window? I am able to, and I can Alt-Enter it too
to get a fully resizable window. Ideally, the main Call Window should
be resizeable like this too, no? I can change the GTK setting to make
it resizable, but I'm unsure of where/how to handle the callbacks to
redraw/scale the video. I am also not able to use Fullscreen when I'm
not in a call session -- ie. when I'm just viewing my local video.
Perhaps this is because the Fullscreen mode requires a remote PIP?

_______________________________________________
ekiga-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/ekiga-list
ekiga-pip-resizing-moving.patch (application/octet-stream, 7.7 KB)
--- ekiga-4.0.1/lib/gui/xwindow.cpp.orig	2013-02-18 16:37:04.000000000 -0500
+++ ekiga-4.0.1/lib/gui/xwindow.cpp	2014-11-08 08:48:35.409687657 -0500
@@ -347,6 +347,10 @@
   XEvent event;
   bool ret = false;
 
+  int slX, slY, pipX, pipY, maX, maY;
+  unsigned int slW, slH, pipW, pipH, maW, maH;
+  float pipR;
+
   XLockDisplay (_display);
   while (XCheckWindowEvent (_display, _XWindow, StructureNotifyMask 
                                               | SubstructureRedirectMask
@@ -365,13 +369,67 @@
                 // the window size has changed
                 XConfigureEvent *xce = &(event.xconfigure);
 
-                    // if a slave window exists it has to be resized as well
-                if (_slave)
-                  _slave->SetWindow (xce->width - (int) (xce->width / ( _state.fullscreen ? PIP_RATIO_FS : PIP_RATIO_WIN)),
-                                     xce->height - (int) (_slave->GetYUVHeight () * xce->width / ( _state.fullscreen ? PIP_RATIO_FS :  PIP_RATIO_WIN) / _slave->GetYUVWidth ()),
-                                     (int) (xce->width / ( _state.fullscreen ? PIP_RATIO_FS :  PIP_RATIO_WIN)),
-                                     (int) (_slave->GetYUVHeight () * xce->width / ( _state.fullscreen ? PIP_RATIO_FS :  PIP_RATIO_WIN) / _slave->GetYUVWidth ()));
+                // if a slave window exists it has to be resized as well
+                if (_slave) {
+                  GetWindow(&maX, &maY, &maW, &maH);
+
+                  if ( (maX != _state.oldx) || (maY != _state.oldy)
+                    || (maW != (unsigned int)_state.oldWidth)
+						  || (maH != (unsigned int) _state.oldHeight) ) {
+   
+                    _slave->GetWindow(&slX, &slY, &slW, &slH);
+
+                    // initialize old values if unset (5000 values are bogus, right?)
+                    if ( _state.oldWidth > 5000 || _state.oldWidth < 15
+                      || _state.oldHeight > 5000 || _state.oldHeight < 15
+                      || abs(_state.oldx) > 5000 || abs(_state.oldy) > 5000 ) {
+                      _state.oldx = maX;
+                      _state.oldy = maY;
+                      _state.oldWidth = maW;
+                      _state.oldHeight = maH;
+                      slX = maX;
+                      slY = maY;
+                      slW = maW / PIP_RATIO_FS;
+                    }
+
+                    pipR = (float) _slave->GetYUVHeight() / _slave->GetYUVWidth();    
+                    pipW = (int) (xce->width * (float) slW / _state.oldWidth);
+                    pipH = (int) (pipW * pipR);
+                    pipX = slX - maX;
+                    pipY = slY - maY;
+
+                    if (pipX > (int)(maW/2)) {
+                      if (pipY > (int)(maH/2)) {
+                        // slave/PIP was in bottom right. Adjust it back there.
+                        pipX = xce->width - pipW;
+                        pipY = xce->height - pipH;
+                      } else {
+                        // top right
+                        pipX = xce->width - pipW;
+                        pipY = 0;
+                      }
+                    }
+                    else {
+                      if (pipY > (int)(maH/2)) {
+                        // bottom left
+                        pipX = 0;
+                        pipY = xce->height - pipH;
+                      } else {
+                        // top left
+                        pipX = 0;
+                        pipY = 0;
+                      }
+                    }
+
+                    _state.oldx = maX;
+                    _state.oldy = maY;
+                    _state.oldWidth = maW;
+                    _state.oldHeight = maH;
 
+                    if (pipH>15) _slave->SetWindow (pipX, pipY, pipW, pipH);
+                   }
+                }
+                
                 CalculateSize (xce->width, xce->height, true);
 
                 if( _paintColorKey ) {
@@ -431,17 +489,86 @@
 
     case ButtonPress:
               // a mouse button is clicked
+              {
+              XButtonEvent *xbn = &(event.xbutton);
+
+              if (xbn->button == Button3) { // right click to resize/reposition PIP
+
+                if (_slave) { // clicked on main (remote) video window
 
-              if (_master)
-                if (!_master->HasDecoration())
-                  _master->ToggleDecoration();
-                else
-                  _master->ToggleFullscreen();
-              else 
-                if (!_state.decoration)
-                  ToggleDecoration();
-                else
-                  ToggleFullscreen();
+                  pipR = (float) _slave->GetYUVHeight() / _slave->GetYUVWidth();
+                  GetWindow(&maX, &maY, &maW, &maH);
+
+                  // if click originated from PIP (HACK: will have negative coords),
+                  // modify xbutton coords to be relative to _master's top-left.
+                  if (xbn->x < 0) {
+                    _slave->GetWindow(&slX, &slY, &slW, &slH);
+
+                    // WTF: for some reason the _slave's (PIP's) x,y coords are
+                    // twice what they should be, relative to _master's top-left (0,0),
+                    // only when _slave is on the right site.
+                    // So we divide the offset by 2. And we remember to un-negativize.
+                    event.xbutton.x = (slX - maX)/2 - xbn->x;
+                    event.xbutton.y = (slY - maY)/2 - xbn->y;
+                  }
+
+                  if (xbn->x > (int)(maW/2)) {
+                    if (xbn->y > (int)(maH/2)) {
+                      // clicked in bottom right quadrant
+                      pipX = xbn->x;
+                      pipW = maW - xbn->x;
+                      pipH = (int) (pipW * pipR); 
+                      pipY = maH - pipH;
+                    } else {
+                      // top right
+                      pipY = 0;
+                      pipX = xbn->x;
+                      pipW = maW - xbn->x;
+                      pipH = (int) (pipW * pipR); 
+                    }
+                  } else {
+                    if (xbn->y > (int)(maH/2)) {
+                      // bottom left
+                      pipX = 0;
+                      pipW = xbn->x;
+                      pipH = (int) (pipW * pipR); 
+                      pipY = maH - pipH;
+                    } else {
+                      // top left
+                      pipX = 0;
+                      pipY = 0;
+                      pipW = xbn->x;
+                      pipH = (int) (pipW * pipR); 
+                    }
+                  }
+
+                  if (pipH>15) _slave->SetWindow (pipX, pipY, pipW, pipH);
+                }
+
+                else if (_master) { // clicked inside PIP window
+                  // bounce the buttonpress event back to the "main" root window.
+                  // Make the coords negative to differentiate such clicks from
+                  // clicks in the main window. (Ie. if the slave window's top-left
+                  // coords are not (0,0).
+                  event.xclient.window = _rootWindow;
+                  event.xbutton.x = - xbn->x;
+                  event.xbutton.y = - xbn->y;
+                  XSendEvent (_display, _rootWindow, FALSE, ButtonPressMask, &event);
+                }
+
+              } else {
+                if (_master)
+                  if (!_master->HasDecoration())
+                    _master->ToggleDecoration();
+                  else
+                    _master->ToggleFullscreen();
+                else 
+                  if (!_state.decoration)
+                    ToggleDecoration();
+                  else
+                    ToggleFullscreen();
+                }
+              }
               break;
 
     case DestroyNotify:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.