[rkward/work/generalized_preview] rkward: Add R function to control window placement.

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Tue Jan 5 13:39:44 UTC 2016


Git commit 50941faf7d3c8b04256ad2652504f2c750d26785 by Thomas Friedrichsmeier.
Committed on 05/01/2016 at 13:39.
Pushed by tfry into branch 'work/generalized_preview'.

Add R function to control window placement.

M  +3    -1    rkward/rbackend/rinterface.cpp
M  +1    -0    rkward/rbackend/rpackages/rkward/NAMESPACE
M  +37   -0    rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
A  +45   -0    rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd
M  +7    -3    rkward/windows/rkwindowcatcher.cpp
M  +11   -6    rkward/windows/rkworkplace.cpp

http://commits.kde.org/rkward/50941faf7d3c8b04256ad2652504f2c750d26785

diff --git a/rkward/rbackend/rinterface.cpp b/rkward/rbackend/rinterface.cpp
index 6c91e91..7e88e31 100644
--- a/rkward/rbackend/rinterface.cpp
+++ b/rkward/rbackend/rinterface.cpp
@@ -2,7 +2,7 @@
                           rinterface.cpp  -  description
                              -------------------
     begin                : Fri Nov 1 2002
-    copyright            : (C) 2002-2014 by Thomas Friedrichsmeier
+    copyright            : (C) 2002-2016 by Thomas Friedrichsmeier
     email                : thomas.friedrichsmeier at kdemail.net
  ***************************************************************************/
 
@@ -625,6 +625,8 @@ QStringList RInterface::processPlainGenericRequest (const QStringList &calllist)
 			RK_ASSERT (calllist.value (1) == "get");
 			return (RKWorkplace::mainWorkplace ()->makeWorkplaceDescription ());
 		}
+	} else if (call == "set.window.placement.hint") {
+		RKWorkplace::mainWorkplace ()->setWindowPlacementOverride (calllist.value (1));
 	} else if (call == "getSessionInfo") {
 		// Non-translatable on purpose. This is meant for posting to the bug tracker, mostly.
 		QStringList lines ("-- Frontend --");
diff --git a/rkward/rbackend/rpackages/rkward/NAMESPACE b/rkward/rbackend/rpackages/rkward/NAMESPACE
index 34d8c1f..1c8eea7 100644
--- a/rkward/rbackend/rpackages/rkward/NAMESPACE
+++ b/rkward/rbackend/rpackages/rkward/NAMESPACE
@@ -44,6 +44,7 @@ export(.rk.variables)
 export(.rk.watch.globalenv)
 export(.rk.watch.symbol)
 export(.rk.watched.symbols)
+export(.rk.with.placement.hint)
 export(RK)
 export(Sys.setlocale)
 export(X11)
diff --git a/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R b/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
index 722792c..c08a74d 100644
--- a/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
+++ b/rkward/rbackend/rpackages/rkward/R/rk.workspace-functions.R
@@ -69,3 +69,40 @@
 	.rk.do.plain.call ("workplace.layout", c ("set", close, lines), synchronous=FALSE)
 	invisible (NULL)
 }
+
+#' Control window placement
+#' 
+#' \code{.rk.with.placement.hint} can be used to make windows appear in a specific
+#' location: attached, detached, or in a named position where a previous window is
+#' found. (The latter used for preview windows, importantly).
+#' 
+#' NOTE: This function is still somewhat experimental, and it is not guaranteed that
+#' it will remain in place, with compatible parameters.
+#' 
+#' @aliases .rk.with.placement.hint rk.with.placement.hint
+#' @param hint a character string specifying the placement in the form "[attached|detached][:name]"
+#'        If a name is given, and this position is not yet known, the attached/detached hint will
+#'        be followed (or, if ommitted, default placement will be used). If later a second window is
+#'        created with the same given name, it will replace the first window.
+#' @param expr Expression to evaluate, unsually an expression that is expected to create exactly one
+#'        new window.
+#' @return \code{NULL}, invisibly.
+#' @author Thomas Friedrichsmeier \email{rkward-devel@@kde.org}
+#' @keywords utilities
+#' @rdname rk.with.placement.hint
+#' @examples
+#' 
+#' ## Not run
+#' .rk.with.placement.hint ("attached", {
+#'    RK ()
+#'    plot (1, 1)
+#' })
+#' ## End not run
+#' 
+#' @export
+".rk.with.placement.hint" <- function (hint, expr) {
+	.rk.do.plain.call ("set.window.placement.hint", as.character (hint), FALSE)
+	on.exit (.rk.do.plain.call ("set.window.placement.hint", "", FALSE))
+	eval.parent (substitute (eval (quote (expr), parent.frame ())))
+	invisible (NULL)
+}
diff --git a/rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd b/rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd
new file mode 100644
index 0000000..2916f4d
--- /dev/null
+++ b/rkward/rbackend/rpackages/rkward/man/rk.with.placement.hint.Rd
@@ -0,0 +1,45 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/rk.workspace-functions.R
+\name{.rk.with.placement.hint}
+\alias{.rk.with.placement.hint}
+\alias{rk.with.placement.hint}
+\title{Control window placement}
+\usage{
+.rk.with.placement.hint(hint, expr)
+}
+\arguments{
+\item{hint}{a character string specifying the placement in the form "[attached|detached][:name]"
+If a name is given, and this position is not yet known, the attached/detached hint will
+be followed (or, if ommitted, default placement will be used). If later a second window is
+created with the same given name, it will replace the first window.}
+
+\item{expr}{Expression to evaluate, unsually an expression that is expected to create exactly one
+new window.}
+}
+\value{
+\code{NULL}, invisibly.
+}
+\description{
+\code{.rk.with.placement.hint} can be used to make windows appear in a specific
+location: attached, detached, or in a named position where a previous window is
+found. (The latter used for preview windows, importantly).
+}
+\details{
+NOTE: This function is still somewhat experimental, and it is not guaranteed that
+it will remain in place, with compatible parameters.
+}
+\examples{
+
+## Not run
+.rk.with.placement.hint ("attached", {
+   RK ()
+   plot (1, 1)
+})
+## End not run
+
+}
+\author{
+Thomas Friedrichsmeier \email{rkward-devel at kde.org}
+}
+\keyword{utilities}
+
diff --git a/rkward/windows/rkwindowcatcher.cpp b/rkward/windows/rkwindowcatcher.cpp
index 3d3589e..c3fdf64 100644
--- a/rkward/windows/rkwindowcatcher.cpp
+++ b/rkward/windows/rkwindowcatcher.cpp
@@ -250,9 +250,11 @@ void RKCaughtX11Window::doEmbed () {
 		RKWardApplication::getApp ()->registerNameWatcher (embedded, this);
 #endif
 	}
-	// make xembed_container resizable, again, now that it actually has a content
-	dynamic_size_action->setChecked (true);
-	fixedSizeToggled ();
+	if (!isAttached ()) {
+		// make xembed_container resizable, again, now that it actually has a content
+		dynamic_size_action->setChecked (true);
+		fixedSizeToggled ();
+	}
 
 	// try to be helpful when the window is too large to fit on screen
 	QRect dims = window ()->frameGeometry ();
@@ -340,6 +342,8 @@ void RKCaughtX11Window::prepareToBeDetached () {
 	RK_TRACE (MISC);
 
 	dynamic_size_action->setEnabled (true);
+	dynamic_size_action->setChecked (true);
+	fixedSizeToggled ();
 	reEmbed ();
 }
 
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index 5aaf8fc..d5f1429 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -211,17 +211,14 @@ void RKWorkplace::detachWindow (RKMDIWindow *window, bool was_attached) {
 void RKWorkplace::addWindow (RKMDIWindow *window, bool attached) {
 	RK_TRACE (APP);
 
-	windows.append (window);
-	connect (window, SIGNAL (destroyed(QObject*)), this, SLOT (removeWindow(QObject*)));
-	connect (window, SIGNAL (windowActivated(RKMDIWindow*)), history, SLOT (windowActivated(RKMDIWindow*)));
-	if (window->isToolWindow () && !window->tool_window_bar) return;
-
 	// a placment override / named window exists
 	if (!placement_override_spec.isEmpty ()) {
 		QString hint = placement_override_spec.section (':', 0, 0);
 		QString name = placement_override_spec.section (':', 1, 1);
 
 		if (hint == "attached") {
+			if (!attached) window->state = RKMDIWindow::Detached;   // Ok, yeah. BAD style. But windows that would go to detached by default would not prepareToBeAttached(), without this.
+			                                                        // TODO: Create third state: NotManaged
 			attached = true;
 		} else if (hint == "detached") {
 			attached = false;
@@ -245,6 +242,7 @@ void RKWorkplace::addWindow (RKMDIWindow *window, bool attached) {
 
 			NamedWindow &nw = named_windows[pos];
 			if (nw.window && nw.window != window) {   // kill existing window (going to be replaced)
+				// TODO: this is not really elegant, yet, as it will change tab-placement (for attached windows), and discard / recreate container (for detached windows)
 				disconnect (nw.window, SIGNAL (destroyed(QObject*)), this, SLOT (namedWindowDestroyed(QObject*)));
 				nw.window->deleteLater ();
 				nw.window = window;
@@ -256,12 +254,19 @@ void RKWorkplace::addWindow (RKMDIWindow *window, bool attached) {
 			else { // custom parent
 				window->prepareToBeAttached ();
 				window->setParent (nw.parent);
-				// TODO: do we have to set window state to attached?
+				// TODO: do this is somewhat inconsistent. But such windows are not attached to the main workplace view, which makes them rather behave detached.
+				window->state = RKMDIWindow::Detached;
+				// NOTE: The window is _not_ added to the window list/window history in this case.
 				return;
 			}
 		}
 	}
 
+	windows.append (window);
+	connect (window, SIGNAL (destroyed(QObject*)), this, SLOT (removeWindow(QObject*)));
+	connect (window, SIGNAL (windowActivated(RKMDIWindow*)), history, SLOT (windowActivated(RKMDIWindow*)));
+	if (window->isToolWindow () && !window->tool_window_bar) return;
+
 	if (attached) attachWindow (window);
 	else detachWindow (window, false);
 }



More information about the rkward-tracker mailing list